POST提交數據之---Content-Type的理解;javascript
Content-Type是指http/https發送信息至服務器時的內容編碼類型,contentType用於代表發送數據流的類型,服務器根據編碼類型使用特定的解析方式,獲取數據流中的數據。css
在網絡請求中,經常使用的Content-Type有以下:
text/html, text/plain, text/css, text/javascript, image/jpeg, image/png, image/gif,
application/x-www-form-urlencoded, multipart/form-data, application/json, application/xml 等。html
其中:text/html, text/plain, text/css, text/javascript, image/jpeg, image/png, image/gif, 都是常見的頁面資源類型。html5
application/x-www-form-urlencoded, multipart/form-data, application/json, application/xml 這四個是ajax的請求,表單提交或上傳文件的經常使用的資源類型。java
form表單中能夠定義enctype屬性,該屬性的含義是在發送到服務器以前應該如何對錶單數據進行編碼。默認的狀況下,表單數據會編碼爲
"application/x-www-form-unlencoded". jquery
enctype經常使用的屬性值以下:application/x-www-form-unlencoded: 在發送前編碼全部字符(默認狀況下);
multipart/form-data, 不對字符編碼。在使用文件上傳時候,使用該值。git
一:application/x-www-form-urlencoded 主要用於以下:
1.1: 最多見的POST提交數據方式。
1.2:原生form默認的提交方式(可使用enctype指定提交數據類型)。
1.3:jquery,zepto等默認post請求提交的方式。github
1. 首先來看下form表單中post默認提交方式的數據;代碼以下:ajax
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> </head> <body> <div id="app"> <form action="http://www.example.com" method="POST"> <p>username: <input type="text" name="fname" /></p> <p>age: <input type="text" name="age" /></p> <input type="submit" value="提交" /> </form> </div> </body> </html>
以下圖所示:chrome
application/x-www-form-urlencoded 是最經常使用的一種請求編碼方式,支持GET/POST等方法,全部數據變成鍵值對的形式 key1=value1&key2=value2
的形式,而且特殊字符須要轉義成utf-8編號,如空格會變成 %20;
默認的提交方式是 application/x-www-form-urlencoded 編碼提交數據的,在chrome的network面板下,默認的請求體是被解析的。展現成formData的形式;
以下是使用ajax的方式提交的;
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script> </head> <body> <div id="app"> <div class="btn">發送post請求</div> </div> <script> var obj = { "name": 'CntChen', "info": 'Front-End', }; $('.btn').click(function() { $.ajax({ url: 'www.example.com', type: 'POST', dataType: 'json', data: obj, success: function(d) { } }) }); </script> </body> </html>
以下圖所示:
如上默認提交的 contentType爲 application/x-www-form-urlencoded,此時提交的數據將會格式化成:
username=111&age=2;
若是請求類型type是GET的話,那麼格式化的字符串將直接拼接在url後發送到服務端; 若是請求類型是POST, 那麼格式化的字符串將放在http body的Form Data中發送。
二:multipart/form-data
使用表單上傳文件時,必須指定表單的 enctype屬性值爲 multipart/form-data. 請求體被分割成多部分,每部分使用 --boundary分割;
html代碼以下:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> </head> <body> <div id="app"> <form action="http://www.example.com" method="POST" enctype="multipart/form-data"> <p>username: <input type="text" name="fname" /></p> <p>age: <input type="text" name="age" /></p> <input type="submit" value="提交" /> </form> </div> </body> </html>
以下圖所示:
三:application/json
在http請求中,ContentType都是默認的值 application/x-www-form-urlencoded, 這種編碼格式的特色是:name/value值對,
每組之間使用&鏈接,而name與value之間是使用 = 鏈接,好比 key=xxx&name=111&password=123456; 鍵值對通常的狀況下是沒有什麼問題的,
是很簡單的json形式,好比以下:
{
a: 1, b: 2 }
它會解析成 a=1&b=2這樣的,可是在一些複雜的狀況下,好比須要傳一個複雜的json對象,也就是對象嵌套數組的狀況下,好比以下代碼:
{
obj: [
{
"name": 111, "password": 22 } ] }
這樣複雜的對象,application/x-www-form-urlencoded這種形式傳遞的話, 會被解析成 obj[0]['name']=111&obj[0].['password']=2這樣的。
而後再轉成json形式;
{
"obj": [ { "name": 111, "password": 22 } ] }
對於一些複製的數據對象,對象裏面再嵌套數組的話,建議使用application/json傳遞比較好,開發那邊也會要求使用application/json。由於他們那邊不使用application/json的話,使用默認的application/x-www-form-urlencoded傳遞的話,開發那邊先要解析成如上那樣的,
而後再解析成json對象,若是對於比上面更復雜的json對象的話,那麼他們那邊是很解析的,因此直接json對象傳遞的話,對於他們來講更簡單。
經過json的形式將數據發送給服務器。json的形式的優勢是它能夠傳遞結構複雜的數據形式,好比對象裏面嵌套數組這樣的形式等。
以下代碼:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script> </head> <body> <div id="app"> <div class="btn">發送post請求</div> </div> <script> $('.btn').click(function() { $.ajax({ url: 'http://www.example.com', type: 'POST', dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}), success: function(d) { } }) }); </script> </body> </html>
可是如上代碼,在瀏覽器運行後,發現跨域了,咱們看以下截圖所示:
3.1 理解ajax跨域設置 ContentType: application/json
在使用ajax跨域請求時,若是設置Header的ContentType爲 application/json,它會發兩次請求,第一次先發Method爲OPTIONS的請求到服務器,
這個請求會詢問服務器支持那些請求方法(好比GET,POST)等。若是這個請求支持跨域的話,就會發送第二個請求,不然的話在控制檯會報錯,第二個請求不會請求。以下咱們作個簡單的demo,不跨域的以下:
以下的代碼:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script> </head> <body> <div id="app"> <div class="btn">發送post請求</div> </div> <script> $('.btn').click(function() { $.ajax({ url: 'http://localhost:8081/api.json', type: 'POST', dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}), success: function(d) { } }) }); </script> </body> </html>
以下圖所示:
如上咱們能夠看到json格式提交的數據會顯示 Request Payload;