先後端聯調之Form Data與Request Payload,你真的瞭解嗎?

前言

作過先後端聯調的小夥伴,可能有時會遇到一些問題。例如,我明明傳遞數據給後端了,後端爲何說沒收到呢?這時候可能就會就會有小夥伴陷入迷茫,本文從chrome-dev-tools(F12調試器)中看到的FormDataRequestBody,給小夥伴們提供一種可能的思路。也給小夥伴們提供一些問題的探究方法。html

簡介

什麼是FormData?什麼是RequestPayload?不解釋,直接上圖:前端

Request Paload

Form Data

區別?

由於這裏觸及了個人知識盲區,因此有了本文。這個答案是我在stackoverflow上獲得的。首先仍是貼問題,貼答案。vue

What's the difference between 「Request Payload」 vs 「Form Data」 as seen in Chrome dev tools Network tab。
中文翻譯:chrome開發者工具中的Request Payload與Form Data有什麼區別?

高票回答:react

The Request Payload - or to be more precise: payload body of a HTTP Request - is the data normally send by a POST or PUT Request. It's the part after the headers and the CRLF of a HTTP Request.ios

A request with Content-Type: application/json may look like this:ajax

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

{ "foo" : "bar", "name" : "John" }

If you submit this per AJAX the browser simply shows you what it is submitting as payload body. That’s all it can do because it has no idea where the data is coming from.chrome

If you submit a HTML-Form with method="POST" and Content-Type: application/x-www-form-urlencoded or Content-Type: multipart/form-data your request may look like this:json

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

foo=bar&name=John

In this case the form-data is the request payload. Here the Browser knows more: it knows that bar is the value of the input-field foo of the submitted form. And that’s what it is showing to you.axios

So, they differ in the Content-Type but not in the way data is submitted. In both cases the data is in the message-body. And Chrome distinguishes how the data is presented to you in the Developer Tools.後端

翻譯過來是說:
Request Payload更準確的說是http request的payload body。通常用在數據經過POST請求或者PUT請求。它是HTTP請求中空行的後面那部分。(PS:這裏涉及一個http常被問到的問題,http請求由哪幾部分組成,通常是請求行,請求頭,空行,請求體。payload body應該是對應請求體。)

一個請求伴隨着header設置爲Content-Type: application/json時候,看起來可能像這樣:

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

{ "foo" : "bar", "name" : "John" }

若是你正常請求一個ajax。瀏覽器會簡單的將你提交的內容做爲payload展現出來,這就是它所能作的,由於它不知道數據來自哪裏。

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

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>

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

clipboard.png

注意點

能夠看到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));可修正要發的內容

axios方式提交

場景構造

因爲axios已是vue、react的準標配請求方式了,因此這裏探究一下它。
首先我門看axios的文檔,當post提交時候能夠傳遞什麼類型參數:

clipboard.png

注意這個類型,咱們分別構造兩個場景。對應它。

function submit3() {
    var sence1 = 'name=123&val=456';
    var sence2 = {name: 123, val: 456};
    axios.post('/', sence1)
}

分別傳遞字符串與對象,提交post請求,而後觀察結果:

場景1——傳遞字符串時候的結果:
字符串提交場景

場景2——傳遞對象的結果:
對象提交場景

注意點

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哈。

後記

原本只是小小的一個問題,仔細研究起來發現挺多細節。今天就花時間整理了一下,但願能給你們一些幫助。碼字不容易,若是感到這篇文章對你有用。點個贊,收個藏唄。

相關文章
相關標籤/搜索