Form Data與Request Payload,你真的瞭解嗎?

前言

今天中午在領完盒飯,吃飯的時候,爲了趕進度,不得不一邊吃飯,一邊敲代碼,爲了給後端傳一張圖片,我用new FormData()把圖片append進去,模擬form表單提交,慌慌張張,匆匆忙忙,覺得弄完就能夠開心的吃飯了,結果後端說沒有收到數據...我明明傳遞數據給後端了,後端爲何說沒收到呢?下面就進入咱們此次的主題html

簡介

什麼是Form Data?什麼是RequestPayloadFormDataPayload瀏覽器傳輸給接口的兩種格式,這兩種方式瀏覽器是經過Content-Type的值來進行區分的:前端

  1. 若是是 application/x-www-form-urlencoded的話,則爲Form Data方式
  2. 若是是application/jsonmultipart/form-data的話,則爲 RequestPayload 的方式。

POST提交中

Content-Type 請求格式
application/x-www-form-urlencoded formdata
application/json request payload
multipart/form-data request payload

MDN的MIME類型這篇文章能夠看到:multipart/form-data 可用於HTML表單從瀏覽器發送信息給服務器。做爲多部分文檔格式,它由邊界線(一個由'--'開始的字符串)劃分出的不一樣部分組成。每一部分有本身的實體,以及本身的 HTTP請求頭,Content-DispositionContent-Type 用於文件上傳領域,最經常使用的 (Content-Length 由於邊界線做爲分隔符而被忽略)。以下圖所示:jquery

Form Data

Content-Type: multipart/form-data; boundary=aBoundaryString

(other headers associated with the multipart document as a whole)

--aBoundaryString
Content-Disposition: form-data; name="myFile"; filename="img.jpg"
Content-Type: image/jpeg

(data)
--aBoundaryString
Content-Disposition: form-data; name="myField"

(data)
--aBoundaryString
(more subparts)
--aBoundaryString--
複製代碼

Request Paload

HTTP請求中 request payload 和 formData 有什麼區別呢?

解釋以下: FormDataPayload瀏覽器傳輸給接口的兩種格式,這兩種方式瀏覽器是經過Content-Type的值來進行區分的,若是是 application/x-www-form-urlencoded的話,則爲Form Data方式,若是是application/jsonmultipart/form-data的話,則爲 RequestPayload 的方式。ios

參考連接: stackoverflow.com/questions/2… 其中的解釋以下:ajax

一個請求伴隨着時候,看起來可能像這樣:chrome

POST /some-path HTTP/1.1
Content-Type: application/json

{ "foo" : "bar", "name" : "John" }
複製代碼

若是你只是簡單的ajax請求。請求的header將設置爲Content-Type: application/json。瀏覽器會簡單的將你提交的內容做爲payload展現出來,這就是它所能作的,由於它不知道數據來自哪裏。json

若是你提交了一個html表單而且配置上了method="post",而且設置了Content-Type: application/x-www-form-urlencoded或者Content-Type: multipart/form-data。那麼你的請求可能長這個樣:axios

POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

foo=bar&name=John
複製代碼

這裏的form-data就是request payload。在這裏,瀏覽器知道更多:它知道bar是提交表單的輸入字段foo的值。這就是它向你展現的。後端

因此區別就是,他們只是由於Content-Type設置的不一樣,並非數據提交方式的不一樣,這兩種提交都會將數據放在message-body中。可是chrome瀏覽器的開發者工具會根據這個ContentType區分顯示方式瀏覽器

到這裏咱們知道了,其實都是放到了 payload中。 那麼具體有什麼區別呢?爲何有時候後端拿不到值呢?這就不得不說對 payload的解析方式了。咱們以幾個 chrome下的測試案例,來理一理這個邏輯。

傳統的Form表單提交場景構造以下:

<form action="/" method="POST">
    <input name="name" type="text">
    <input name="password" type="text">
    <button>提交</button>
</form>
複製代碼

若是我這裏點擊提交按鈕,就會觸發瀏覽器的提交功能,那結果是什麼樣呢?

注意點

能夠看到Content-Typeapplication/x-www-form-urlencoded。 值的形式是以key1=value1&key2=value2的形式提交的。

傳統的ajax提交 場景構造

function submit2() {
    var xhr = new XMLHttpRequest();
    xhr.timeout = 3000;
    var obj = {a: 1, b: 2};
    xhr.open('POST', '/');
    xhr.send(obj);
}
複製代碼

首先咱們構造一個簡單的函數,而後觸發它。經過chrome反饋來看:

傳統ajax提交須要注意如下幾點

  1. 默認的Content-Typetext/plain
  2. Request Payload會對非字符串作字符串轉換。
  3. 經過xhr.send(JSON.stringify(obj));可修正要發的內容

注意點

  1. 當咱們傳遞字符串的時候,Content-Type自動轉爲xxx-form-xxx的形式。當爲對象的時候,自動轉化爲xxx/json
  2. 字符串的時候以key1=val1&key2=val2的形式體現,對象以JSON字符串形式體現。

總結

Content-Type的差別

  1. 傳統的ajax請求時候,Content-Type默認爲文本類型。
  2. 傳統的form提交的時候,Content-Type默認爲Form類型。
  3. axios傳遞字符串的時候,Content-Type默認爲Form類型。
  4. axios傳遞對象的時候,Content-Type默認爲JSON類型。

Content-Type的值,Form非Form時,payload的區別:

  1. 都只支持字符串類型(以上探究的幾種狀況)
  2. Form須要傳遞的格式爲key1=value1&key2=value2,相似GET請求的QueryString格式
  3. Form通常爲JSON.stringify(formDataObject)形式

所以後端若是取不到值,不管何種形式傳遞,後端解析表單信息的時候,會考慮Content-Type。若是是JSON字符串的話,後端解析payload的內容時候,確定要去解析JSON。若是是key1=value1&key2=value2的形式,則須要去分割字符串。這些事情通常後端使用的框架會去處理,可是框架給後端提供取值接口有多是不一樣的,因此前端的小夥伴在處理請求問題時,必定要跟後端小夥伴商量好,是用JSON仍是FormData

參考資料:

  1. MIME 類型
  2. Content-Type
  3. How to set a boundary on a multipart/form-data request while using jquery ajax FormData() with multiple files

常見的媒體格式類型以下:

  • text/html : HTML格式
  • text/plain :純文本格式
  • text/xml: XML格式
  • image/gif :gif圖片格式
  • image/jpeg :jpg圖片格式
  • image/png:png圖片格式

application開頭的媒體格式類型:

  • application/xhtml+xml :XHTML格式
  • application/xml: XML數據格式
  • application/atom+xml :Atom XML聚合格式
  • application/json: JSON數據格式
  • application/pdf:pdf格式
  • application/msword : Word文檔格式
  • application/octet-stream : 二進制流數據(如常見的文件下載)
  • application/x-www-form-urlencoded<form encType=」」>中默認的encTypeform表單數據被編碼爲key/value格式發送到服務器(表單默認的提交數據的格式)

另一種常見的媒體格式是上傳文件之時使用的:

  • multipart/form-data : 須要在表單中進行文件上傳時,就須要使用該格式
相關文章
相關標籤/搜索