HTML5 URI данных завершается ошибкой, когда за нулем base64 следует символ =? - PullRequest
2 голосов
/ 04 июня 2011

Я делаю довольно ужасные вещи с JavaScript, и у меня возникла странная проблема.

Я создаю двоичные данные, которые заполняют буфер статического размера.Если содержимое не заполняет буфер, остаток заполняется нулевыми символами.

Следующим шагом является преобразование в base64.

Размер (в байтах) не всегда кратениз 3, так что мне может понадобиться добавить отступ до конца.Последние байты в буфере всегда равны нулю (фактически, это около килобайта нулей).

Когда я конвертирую это в base64 в Firefox и Chrome, я получаю ERR_INVALID_URL, когда у меня есть трейлинг '=', но скачивается нормально, когда нет.

Например:

var url = "data:application/octet-stream;base64,";

window.open(url + "AAAA"); // works
window.open(url + "AAAA="); // doesn't work
window.open(url + "icw="); // works

Мои файлы работают, но они не соответствуют спецификации.

Есть ли причина, по которой это недопустимое base64? Что более важно, это ошибка или часть спецификации?

Редактировать:

Я опубликовал ответ, который даетнекоторые странности между Firefox и Chrome.Кто-нибудь знает, что указывает стандарт?Или это одна из тех слабых спецификаций, которая вызывает фрагментацию?Я хотел бы что-то определенное, если это возможно.

Ответы [ 3 ]

5 голосов
/ 04 июня 2011

Символ заполнения = используется для заполнения кратного четырем кодовым символам.Поскольку каждые три байта ввода отображаются на четыре байта вывода, количество входных байтов, не кратное трем, требует заполнения (для остатка одного байта требуется ==, а для остатка двух байтов требуется =).

В вашем случае AAAA уже является допустимым кодовым словом и не требует заполнения.

2 голосов
/ 04 июня 2011

Примечания о разных браузерах:

  • Chrome
    • datalength % 4 === 1 - необходим один равный
    • datalength % 4 === 2 - необходимо два равных
  • Firefox - знаки равенства необязательны, но следуют тем же соглашениям, что и в Chrome

Это строка, которую я использовал для проверки (я заменял AAAAAA == на новую строку каждый раз):

var url = "data:application/octet-stream;base64,AAAAAA=="; window.open(url);

Кроме того, Firefox и Chrome используют + & /, а не - и _.

Источник:

Мои тесты на Ubuntu 11.04 с Chrome 11 и Firefox 4.

Edit:

Код, для которого это нужно, - утилита tar для Javascript . Мой код работает как есть, но я бы хотел быть как можно более совместимым со стандартами, и мне кажется, что мне не хватает байта. Не важно, потому что tar в Linux распознает это.

2 голосов
/ 04 июня 2011

Почему вы представляете, что добавление символа "=" в конец строки будет работать?Это недопустимый символ в base64.

Набор символов состоит из прописных и строчных букв;цифры;и "+" и "/".Следовательно, все остальное недопустимо в строке base64.

edit - хорошо для URL кажется, что вместо "+" и "/" вы используете "-" и "_" (для позиций 62 и 63 в наборе символов).

отредактируйте еще - это очень запутанная тема из-за существования различных, по-видимому, авторитетных, но противоречивых источников информации.Например, описание Mozilla схемы URL данных не упоминает об использовании альтернативной кодировки «дружественный к имени файла».То же самое относится и к URL-адресу данных IETF RFC.Тем не менее, другие документы IETF четко обсуждают и определяют вариант с помощью «-» и «_», заменяя проблемные (для имен файлов) «+» и «/".

. Поэтому я объявляю себя невежественным :-)Гамбо, вероятно, прав, что жалобы, которые вы получаете, касаются неправильного заполнения (то есть заполнения, когда заполнение фактически не требуется).

...