IETF RFC документы

Роль IETF в экосистеме интернационализации

IETF (Internet Engineering Task Force) определяет набор технических стандартов, описанных в форме RFC (Request for Comments), которые лежат в основе сетевых протоколов, форматов данных и правил интероперабельности в интернете. В контексте интернационализации JavaScript API именно RFC-документы задают фундаментальные правила для представления языков, регионов, кодировок и культурных параметров.

JavaScript Internationalization API (Intl) опирается не только на спецификацию ECMAScript, но и на внешние стандарты, определяющие:

  • структуру языковых тегов
  • правила сопоставления языков
  • форматы локалей
  • семантику региональных идентификаторов

Ключевым элементом является то, что JavaScript не изобретает собственную модель локалей, а строго следует уже существующим RFC-стандартам, обеспечивая совместимость с браузерами, операционными системами и международными библиотеками (ICU, CLDR).


BCP 47 как основа языковых тегов

Основной стандарт, используемый в Intl, — BCP 47 (Best Current Practice 47). Это не один документ, а связка нескольких RFC:

  • RFC 5646 — Tags for Identifying Languages
  • RFC 4647 — Matching of Language Tags
  • RFC 6067 и последующие уточнения (расширения и регистрация подтегов)

BCP 47 определяет формат языкового тега, который используется в Jav * aScript:

language[-script][-region][-variant]

Примеры:

  • en — английский
  • en-US — американский английский
  • sr-Cyrl-RS — сербский, кириллица, Сербия
  • zh-Hans-CN — китайский упрощённый, Китай

RFC 5646 и структура языкового тега

RFC 5646 задаёт строгие правила:

  • язык задаётся ISO 639 (двух- или трёхбуквенные коды)
  • регион — ISO 3166-1 alpha-2
  • письменность — ISO 15924
  • дополнительные варианты — зарегистрированные подтипы

Важное свойство RFC 5646 — расширяемость. Если система встречает неизвестный подтип, он сохраняется, но не интерпретируется.


RFC 4647: алгоритмы сопоставления языков

RFC 4647 описывает механизм matching (сопоставления) языковых тегов. Это критически важно для Intl.DateTimeFormat, Intl.NumberFormat и особенно для Intl.Collator.

Основные стратегии matching:

  • Lookup matching — поиск наиболее близкого совпадения
  • Filtering matching — выбор всех подходящих локалей

JavaScript использует эти механизмы при выборе локали, когда запрошенная недоступна в окружении.

Пример поведения:

  • запрошено fr-CA
  • доступно fr
  • результат: fallback на fr

RFC 5646 и расширения Unicode

BCP 47 включает механизм расширений, особенно Unicode extension subtags. Они используются напрямую в Intl.

Пример:

en-US-u-ca-gregory-nu-latn

Здесь:

  • u — Unicode extension
  • ca-gregory — календарь
  • nu-latn — система чисел (латинская)

Эти расширения стандартизированы Unicode Consortium, но формат их включения определён именно RFC 5646.


RFC 3066 и историческое наследие

До RFC 5646 существовал RFC 3066, который задавал более простую модель языковых тегов. Он поддерживал только базовые конструкции без расширенных подтипов.

Переход:

  • RFC 3066 → RFC 1766 → RFC 5646

Эволюция отражает рост требований интернационализации, особенно в веб-среде и языковых системах операционных систем.


RFC и обработка локалей в Intl API

Intl.Locale и парсинг RFC 5646

Intl.Locale напрямую работает с BCP 47 тегами. При создании объекта происходит разбор строки согласно RFC-правилам:

const loc = new Intl.Locale("en-Latn-US-u-ca-gregory");

Внутри выполняется:

  • токенизация строки
  • проверка синтаксиса BCP 47
  • выделение основных компонентов
  • обработка Unicode extension

Нормализация локалей

RFC-стандарты требуют нормализации:

  • регистр языка: lower-case (en)
  • регион: upper-case (US)
  • script: Title Case (Latn)

JavaScript Intl приводит входные данные к каноническому виду:

en-us → en-US
EN-latn-us → en-Latn-US

RFC 7231 и связь с локализацией HTTP (косвенное влияние)

Хотя RFC 7231 напрямую относится к HTTP/1.1, он определяет заголовок:

Accept-Language

Этот заголовок использует те же BCP 47 теги, что и Intl. Таким образом:

  • браузер получает список предпочтительных языков
  • передаёт их серверу
  • JavaScript использует аналогичную модель для выбора локали

Пример:

Accept-Language: fr-CH, fr;q=0.9, en;q=0.8

RFC 5234 и формальные грамматики ABNF

Многие RFC используют ABNF (Augmented Backus-Naur Form), описанный в RFC 5234, для формального задания синтаксиса.

BCP 47 также опирается на ABNF для определения структуры языкового тега:

Language-Tag = langtag
langtag = language ["-" script] ["-" region] *("-" variant)

Эта формализация важна для:

  • парсеров в браузерах
  • ICU библиотек
  • реализации Intl API в V8, SpiderMonkey, JavaScriptCore

RFC и совместимость реализаций Intl

ICU как слой реализации

Intl API в большинстве движков опирается на ICU (International Components for Unicode), который реализует RFC-совместимую модель локалей.

ICU:

  • интерпретирует BCP 47
  • реализует fallback стратегии RFC 4647
  • обрабатывает Unicode extensions

Поведение fallback в разных движках

Несмотря на общий стандарт RFC, реализация может различаться:

  • список поддерживаемых локалей
  • поведение при неизвестных тегах
  • стратегия выбора дефолтной локали

Однако синтаксис и структура строго унифицированы через RFC 5646.


RFC и сортировка строк (Intl.Collator)

RFC напрямую не определяет алгоритмы сортировки, но BCP 47 влияет на выбор правил сортировки:

new Intl.Collator("sv-SE");

Здесь локаль sv-SE определяет:

  • алфавитные правила
  • порядок символов
  • диакритические различия

ICU использует локаль как ключ к collation tailoring, который соответствует языковым стандартам Unicode, но инициируется через RFC-идентификаторы.


Взаимодействие RFC и Unicode CLDR

RFC определяет формат идентификаторов, а CLDR (Common Locale Data Repository) определяет данные:

  • названия месяцев
  • форматы дат
  • правила множественного числа
  • числовые системы

Связка выглядит так:

  • RFC 5646 → идентификатор локали
  • CLDR → данные локали
  • Intl API → интерфейс доступа

Расширения RFC в экосистеме ECMAScript

ECMAScript Internationalization API Specification не заменяет RFC, а расширяет их использование:

  • добавляет программные интерфейсы
  • стандартизирует поведение fallback
  • определяет обработку ошибок парсинга BCP 47

RFC остаются «низкоуровневым языком описания», а Intl — высокоуровневым API.


Ошибки парсинга и строгие правила RFC

При нарушении BCP 47 синтаксиса возникает RangeError:

new Intl.Locale("invalid_locale_123");

Причины:

  • отсутствие языка
  • неверный формат региона
  • недопустимые символы
  • нарушение ABNF структуры RFC

RFC требует строгого соответствия, так как локали должны быть однозначно интерпретируемыми во всех системах.


Значение RFC для кросс-платформенной интернационализации

RFC обеспечивает:

  • единый формат языковых идентификаторов
  • совместимость между браузерами и серверными системами
  • предсказуемость поведения Intl API
  • интеграцию с HTTP, OS и библиотеками Unicode

Без RFC 5646 и RFC 4647 интернационализация в JavaScript была бы фрагментированной и зависимой от конкретной платформы.