2013-05-25 2 views
8

За годы, прошедшие с ознакомления с меняющимися спецификациями, я предположил, что RFC 3986 окончательно установил кодировку UTF-8 для последовательностей escape-октетов. То есть, если мой URI имеет %XX%YY%ZZ, я могу взять эту последовательность декодированных октетов (для любого URI в части, относящейся к схеме) и интерпретировать полученные байты как UTF-8, чтобы узнать, какая была расшифрованная информация. На практике я могу назвать JavaScript decodeURIComponent(), который автоматически выполняет это декодирование для меня.Charset in data URI

Затем я прочитал спецификацию для data: URIs, RFC 2397, который включает в себя charset аргумент, который (естественно) указывает набор символов закодированных данных. Но как это работает? Если у меня есть двухоктевая кодированная последовательность %XX%YY в моем data: URI, то charset=iso-8859-1 указывает, что два декодированных вектора должны не быть интерпретированы как последовательность UTF-8, а как два отдельных латинских символа (как каждый байт в ISO -8859-1 - символ)? RFC 2397, кажется, указывает на это, так как это дает пример «греческих символов [так в оригинале]»:

data:text/plain;charset=iso-8859-7,%be%fg%be 

Но это означает, что JavaScript decodeURIComponent() (который предполагает UTF-8 закодированных октета) не может быть использована для извлечения строка из URI данных, правильно? Означает ли это, что мне нужно создать собственное декодирование для URI данных, если кодировка - это нечто помимо UTF-8?

Кроме того, означает ли это, что RFC 2397 теперь находится в конфликте с RFC 3986, что, как представляется, указывает на то, что UTF-8 предполагается? Или RFC 3986 ссылается только на «новую схему URI [s]», что означает, что схема URI data: получает grandfathered и имеет свой собственный метод определения того, что означает кодированные октеты?

Моя лучшая догадка заключается в том, что data: играет по своим собственным правилам, и если это указывает на кодировку, отличную от UTF-8, мне придется использовать что-то отличное от decodeURIComponent() в JavaScript. Любые рекомендации по методу замены также приветствуются.

ответ

5

Помните, что схема data: URI описывает ресурс, который можно рассматривать как файл, который состоит из непрозрачного потокового так же, как если бы это были http: URI (тот же потоковое, но хранится на сервере HTTP) или ftp: URI (тот же самый поток, но сохраненный на FTP-сервере) или URI file: (тот же самый поток, но сохраненный в локальной файловой системе). Только метаданные, прикрепленные к файлу, дают значение bytestream.

RFC 2397 дает четкую спецификацию о том, как этот байтовый поток должен быть встроен в сам URI (в отличие от других схем URI, где URI дает инструкции о том, где взять байтовый поток, а не то, что он содержит). Это может быть base64, или это может быть метод процентного кодирования, указанный в RFC. Base64 будет более компактным, если байтовый поток содержит man-байты, отличные от ASCII.

URI также описывает собственный Content-Type, который дает предполагаемую интерпретацию байтового потока. В этом случае, поскольку вы использовали text/plain;charset=iso-8859-7, байты должны быть правильно закодированы в тексте ISO-8859-7. Байты будут определенно не быть решен как UTF-8 или любая другая кодировка символов. Он будет недвусмысленно декодироваться с использованием кодировки символов, которую вы указали.