Więcej
application/x-www-form-urlencoded lub multipart/form-data?
W HTTP są dwa sposoby na POST danych: application/x-www-form-urlencoded
i multipart/form-data
. Rozumiem, że większość przeglądarek jest w stanie przesyłać pliki tylko wtedy, gdy multipart/form-data
jest używane. Czy są jakieś dodatkowe wskazówki kiedy używać jednego z typów kodowania w kontekście API (bez udziału przeglądarki)? Może to być np. oparte na:
- rozmiar danych
- występowanie znaków innych niż ASCII
- istnienie (niezakodowanych) danych binarnych
- konieczność przesłania dodatkowych danych (jak nazwa pliku)
Jak dotąd nie znalazłem w sieci żadnych formalnych wytycznych dotyczących stosowania różnych typów zawartości.
1262
3
TL;DR
Podsumowanie; jeśli masz binarne (niealfanumeryczne) dane (lub znacznej wielkości ładunek) do przesłania, użyj
multipart/form-data
. W przeciwnym razie, użyjapplication/x-www-form-urlencoded
.Typy MIME, o których wspominasz to dwa nagłówki
Content-Type
dla żądań HTTP POST, które muszą być obsługiwane przez agentów użytkownika (przeglądarki). Celem obu tych typów żądań jest wysłanie listy par nazwa/wartość do serwera. W zależności od rodzaju i ilości przesyłanych danych, jedna z metod będzie bardziej wydajna niż druga. Aby zrozumieć dlaczego, musisz spojrzeć na to, co każda z nich robi pod przykrywką.Dla
application/x-www-form-urlencoded
, treść wiadomości HTTP wysyłanej do serwera jest w zasadzie jednym wielkim ciągiem zapytania -- pary nazwa/wartość są oddzielone ampersandem (&
), a nazwy są oddzielone od wartości symbolem równości (=
). Przykładem tego może być:MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
.Zgodnie ze specyfikacją:
Oznacza to, że dla każdego niealfanumerycznego bajtu, który istnieje w jednej z naszych wartości, potrzeba trzech bajtów do jego reprezentacji. Dla dużych plików binarnych, potrojenie ładunku będzie wysoce nieefektywne.
W tym miejscu z pomocą przychodzi
multipart/form-data
. Z tą metodą przesyłania par nazwa/wartość, każda para jest reprezentowana jako "część" w wiadomości MIME (jak opisano w innych odpowiedziach). Części są oddzielone określonym łańcuchem granicznym (wybranym specjalnie tak, aby ten ciąg graniczny nie występował w żadnym z "wartości" payloads). Każda część ma swój własny zestaw nagłówków MIME, takich jakContent-Type
, a zwłaszczaContent-Disposition
, które mogą nadać każdej części jej "nazwę." Wartość każdej pary nazwa-wartość jest ładunkiem każdej części wiadomości MIME. Specyfikacja MIME daje nam więcej opcji podczas reprezentowania wartości - możemy wybrać bardziej wydajne kodowanie danych binarnych, aby zaoszczędzić przepustowość (np. base 64 lub nawet raw binary).Dlaczego nie używać
multipart/form-data
przez cały czas? Dla krótkich wartości alfanumerycznych (jak większość formularzy internetowych), narzut dodawania wszystkich nagłówków MIME będzie znacznie przewyższał jakiekolwiek oszczędności z bardziej wydajnego kodowania binarnego.Nie sądzę, że HTTP jest ograniczony do POST w multipart lub x-www-form-urlencoded. Nagłówek [Content-Type][1] jest ortogonalny do metody HTTP POST (możesz wypełnić typ MIME, który ci odpowiada). Tak jest również w przypadku typowych webapps opartych na reprezentacji HTML (np. json payload stał się bardzo popularny do przekazywania payload dla żądań ajaxowych).
Jeśli chodzi o Restful API po HTTP, najpopularniejsze typy zawartości z jakimi miałem styczność to application/xml oraz application/json.
application/xml:
Zgadzam się z tym, co powiedział Manuel. W rzeczywistości jego uwagi odnoszą się do tego adresu url...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... który mówi:
Jednak dla mnie sprowadziłoby się to do wsparcia narzędzia / pracy.
Jeśli masz jasne wyobrażenie o swoich użytkowników, i jak oni'll korzystać z API, a następnie, że pomoże Ci zdecydować. Jeśli zrobisz przesyłanie plików trudne dla użytkowników API wtedy oni'll przenieść się, z you'll spędzić dużo czasu na wspieranie ich.
Wtórnie do tego byłoby wsparcie narzędzia masz do pisania API i jak łatwo jest dla Ciebie, aby pomieścić jeden mechanizm przesyłania nad innymi.