ПРОЧИТАЙТЕ КАК ПЕРВЫЙ ПАРА ЗДЕСЬ!
Я знаю, что это на 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 формирует docs , например, использование «blob» в качестве границы при отправке двоичных данных - не очень хорошо. Однако что-то вроде "! Blob!" никогда не появится в выводе base64
.