application/x-www-form-urlencoded або multipart/form-data?
У HTTP існує два способи POST даних: application/x-www-form-urlencoded
і multipart/form-data
. Я розумію, що більшість браузерів можуть завантажувати файли, тільки якщо використовується multipart/form-data
. Чи є якісь додаткові вказівки, коли слід використовувати один з типів кодування в контексті API (без участі браузера)? Це може, наприклад, базуватися на
- розмір даних
- наявність не-ASCII символів
- наявність (некодованих) двійкових даних
- необхідність передачі додаткових даних (наприклад, імені файлу)
Наразі я не знайшов в Інтернеті жодних офіційних рекомендацій щодо використання різних типів контенту.
1262
3
TL;DR
Підсумок; якщо вам потрібно передати двійкові (не алфавітно-цифрові) дані (або значне за розміром корисне навантаження), використовуйте
multipart/form-data
. В іншому випадку використовуйтеapplication/x-www-form-urlencoded
.Згадані вами MIME-типи - це два заголовки
Content-Type
для HTTP POST-запитів, які повинні підтримуватися користувацькими агентами (браузерами). Метою обох цих типів запитів є надсилання списку пар ім'я/значення на сервер. Залежно від типу та обсягу даних, що передаються, один з методів буде більш ефективним, ніж інший. Щоб зрозуміти чому, потрібно подивитися на те, що кожен з них робить "під ковдрою".Для
application/x-www-form-urlencoded
тіло HTTP-повідомлення, що відправляється на сервер, по суті є одним гігантським рядком запиту - пари ім'я/значення розділені амперсандом (&
), а імена відокремлюються від значень символом рівності (=
). Прикладом може бути:МояЗміннаОдин=ЗначенняОдин&МояЗміннаДва=ЗначенняДва
Відповідно до специфікації:
Це означає, що для кожного неалфавітно-цифрового байта, який існує в одному з наших значень, знадобиться три байти для його представлення. Для великих двійкових файлів потроєння корисного навантаження буде вкрай неефективним.
Ось тут і з'являється
multipart/form-data
. При такому способі передачі пар ім'я/значення кожна пара представляється як &quo ;частина&quo ; в MIME-повідомленні (як описано в інших відповідях). Частини відокремлюються певною межею рядка (вибраною спеціально для того, щоб цей граничний рядок не зустрічався в жодному з &quo ;значень&quo ; корисного навантаження). Кожна частина має свій власний набір MIME-заголовків, таких якContent-Type
, і особливоContent-Disposition
, які можуть дати кожній частині її &quo ;ім'я.&quo ; Фрагмент значення кожної пари ім'я/значення є корисним навантаженням кожної частини MIME-повідомлення. Специфікація MIME надає нам більше можливостей при представленні корисного навантаження значення - ми можемо вибрати більш ефективне кодування двійкових даних для економії смуги пропускання (наприклад, база 64 або навіть сирий двійковий код).Чому б не використовувати
multipart/form-data
весь час? Для коротких алфавітно-цифрових значень (як у більшості веб-форм) накладні витрати на додавання всіх MIME-заголовків значно переважать будь-яку економію від більш ефективного двійкового кодування.Я не думаю, що HTTP обмежується POST в багатокомпонентному або x-www-form-urlencoded. Заголовок [Content-Type Header][1] ортогональний методу HTTP POST (ви можете заповнити MIME-тип, який вам підходить). Це також стосується типових веб-додатків, заснованих на представленні HTML (наприклад, json став дуже популярним для передачі корисного навантаження для ajax-запитів).
Що стосується Restful API через HTTP, то найпопулярнішими типами контенту, з якими я стикався, є application/xml та application/json.
application/xml:
Багато з чим з того, що сказав Мануель, я згоден. Власне, в його коментарях є посилання на цей url...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... де сказано:
Однак, як на мене, це зводилося б до підтримки інструменту/фреймворку.
Якщо ви отримаєте чітке уявлення про своїх користувачів і про те, як вони будуть використовувати ваш API, це допоможе вам прийняти рішення. Якщо ви ускладните завантаження файлів для користувачів вашого API, вони відійдуть, і ви витратите багато часу на їх підтримку.
Вторинним по відношенню до цього буде підтримка інструменту, який ви маєте для написання вашого API, і наскільки легко вам пристосувати один механізм завантаження до іншого.