ЧИТАЙТЕ МЕНЬШЕ ПЕРВЫЙ ПАРА ЗДЕСЬ!
Я знаю, что это на 3 года позже, но ответ Мэтта (принятый) неполон и в конечном итоге приведет к неприятностям. Ключевым моментом здесь является то, что, если вы решите использовать multipart/form-data
, граница не должна появляться в данных файла, которые в итоге получает сервер.
Это не проблема application/x-www-form-urlencoded
, потому что нет границ. x-www-form-urlencoded
также всегда может обрабатывать двоичные данные, просто превратив один произвольный байт в три 7BIT
байта. Неэффективно, но это работает (и обратите внимание, что комментарий о невозможности отправить имена файлов, а также двоичные данные неверен; вы просто отправляете его как другую пару ключ / значение).
Проблема в multipart/form-data
том, что в данных файла не должен присутствовать разделитель границ (см. RFC 2388 ; раздел 5.2 также содержит довольно слабое оправдание отсутствия надлежащего агрегатного MIME-типа, позволяющего избежать этой проблемы).
Таким образом, на первый взгляд, multipart/form-data
имеет никакой ценности в любой загрузке файла, двоичном или иным образом . Если вы не выберете свою границу правильно, то у вас в конечном итоге возникнет проблема, отправляете ли вы простой текст или необработанный двоичный файл - сервер найдет границу не в том месте, и ваш файл будет усечен, или POST не удастся.
Ключ должен выбрать кодировку и границу, чтобы выбранные символы границы не могли появиться в закодированном выводе. Одним из простых решений является использование base64
( не используйте необработанный двоичный файл). В base64 3 произвольных байта кодируются в четыре 7-битных символа, где набор выходных символов [A-Za-z0-9+/=]
(т.е. буквенно-цифровые символы , «+», «/» или «=»). =
это особый случай, и может появляться только в конце закодированного вывода, как одинарный =
или двойной ==
. Теперь выберите вашу границу в виде 7-битной строки ASCII, которая не может появиться в base64
выходных данных. Многие варианты, которые вы видите в сети, не проходят этот тест - MDN формирует документыНапример, использовать «blob» в качестве границы при отправке двоичных данных - не очень хорошо. Однако что-то вроде "! Blob!" никогда не появится в base64
выводе.