HTTP content-type及POST提交數據方式


Content-Type(內容類型),一般指網頁中存在的Content-Type,用於定義網絡文件的類型和網頁的編碼,決定瀏覽器將以什么形式、什么編碼讀取這個文件,這也是一些網頁點擊的結果卻是一個文件或一張圖片的原因。

Content-Type 是請求報文和響應報文的實體部分使用的頭部,標識實際返回實體主體的媒體類型。

語法:

Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=something

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

  • 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=””>中默認的encType,form表單數據被編碼為key/value格式發送到服務器(表單默認的提交數據的格式)

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

  • multipart/form-data : 需要在表單中進行文件上傳時,就需要使用該格式

 

POST提交數據的方式

  1、application/x-www-form-urlencoded 

    在發送到服務器前,使用URL的percent-encoding(百分號編碼)編碼所有的字符。

    之所以叫百分號編碼,是因為它的編碼方式非常簡單,使用%加上兩位的字符(012345678ABCDEF)代表一個字節的十六進制形式。URL 編碼默認使用的字符集是US-ASCII。例如a在US-ASCII碼中對應的字節是0x61,那么URL編碼后得到的就是%61。

    如保留字符的URL編碼

! * " ' ( ) ; : @ & = + $ , / ? % # [ ]
%21 %2A %22 %27 %28 %29 %3B %3A %40 %26 %3D %2B %24 %2C %2F %3F %25 %23 %5B %5D

    這也是最常見的POST|提交方式,瀏覽器的原生<form>表單,如果不設置enctype屬性,那么最終會以application/x-www-form-urlencoded 方式提交數據。

    URL編碼詳情見本文附錄。

 

  例如 JQuery 和 QWrap 的 Ajax,Content-Type 默認值都是「application/x-www-form-urlencoded;charset=utf-8」

  使用這種方式,抓包看到的請求是這樣的:

POST http://xxx/query.json HTTP/1.1
Host: xxx
Connection: keep-alive
Content-Length: 294
Accept: */*
Origin: xxx
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: xxx
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=aaa1xsjvLKCZC-beX0-1w

sEcho=1&iColumns=7&sColumns=&iDisplayStart=0&iDisplayLength=10&mDataProp_0=id&mDataProp_1=schemeId&mDataProp_2=redeemNo&mDataProp_3=redeemCode&mDataProp_4=function&mDataProp_5=function&mDataProp_6=function&schemeId=160425SCH1461578754536&num=&comment=&source=&expiretime=&attachmentName=&state=

  請求參數是key/value的形式,並以&符拼接在一起,但是不會在請求URL中顯示。

 

  2、multipart/form-data

  我們使用表單上傳文件時,必須設置 <form> 表單的enctype屬性 等於 multipart/form-data。

  使用這種方式,抓包看到的請求是這樣的:

POST http://xxx HTTP/1.1
Host: xxx
Connection: keep-alive
Content-Length: 356
Accept: application/json, text/javascript, */*; q=0.01
Origin: xxx
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5SBLMDU5DZ2Hmqej
Referer: xxx
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=aaa1xsjvLKCZC-beX0-1w

------WebKitFormBoundary5SBLMDU5DZ2Hmqej
Content-Disposition: form-data; name="file"; filename="xxx.sql"
Content-Type: application/octet-stream

use xxx;
insert into xxx;
------WebKitFormBoundary5SBLMDU5DZ2Hmqej--

 

  3、application/json  (推薦使用)

  用來告知服務器消息主體(body)是序列化后的JSON字符串。使用此種方式需要解析request中的body獲取請求數據。

  使用Spring的話用@RequestBody注解來解析請求參數,這個注解說明參數是從HTTP的body中去獲取。

  使用這種方式,抓包看到的請求是這樣的:

POST http://xxx HTTP/1.1
Host: xxx
Connection: keep-alive
Content-Length: 160
Accept: application/json, text/javascript, */*; q=0.01
Origin: xxx
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36
Content-Type: application/json
Referer: xxx
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=aaa1xsjvLKCZC-beX0-1w

{"schemeId":"160425SCH1461578754536","attachmentName":"xxx.sql","num":"30","comment":"test","expiretime":"2019-09-01"}

 

  4、text/xml 

  XML-RPC(XML Remote Procedure Call,它是一種使用 HTTP 作為傳輸協議,XML 作為編碼方式的遠程調用規范

  不過這種方式暫時沒有用過。

 

附錄:

  URL編碼與解碼

  對於URL來說,編碼是為了消除歧義。如POST使用Content-Type:application/x-www-form-urlencoded 方式提交數據時,URL參數字符串之間使用【key=value&key=value】的形式來傳輸,鍵值之間以&符拼接和分割,那么如果參數名key或者參數值value中包含了=或者&符號勢必會造成接收URL的服務器解析錯誤,因此必須對引起歧義的符號進行轉義,也就是編碼。

  URL的編碼格式采用ASCII碼,也就是說,不能在URL中包含任何非ASCII字符,例如中文。

  RFC3986文檔規定,URL中只允許包含英文字母(a-zA-Z)、數字、-_.~ 4個特殊字符以及所有保留字符。URL編碼中的10-7F字節全部都表示控制字符,這些字符都不能放在URL中。

  RFC3986中指定了以下字符為保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ]

  不安全字符:還有一些字符,當他們直接放在Url中的時候,可能會引起解析程序的歧義。這些字符被視為不安全字符,原因有很多。

    空格:Url在傳輸的過程,或者用戶在排版的過程,或者文本處理程序在處理Url的過程,都有可能引入無關緊要的空格,或者將那些有意義的空格給去掉。
    引號以及<>:引號和尖括號通常用於在普通文本中起到分隔Url的作用
    #:通常用於表示書簽或者錨點
    %:百分號本身用作對不安全字符進行編碼時使用的特殊字符,因此本身需要編碼
    {}|\^[]`~:某一些網關或者傳輸代理會篡改這些字符

  需要注意的是,對於Url中的合法字符,編碼和不編碼是等價的。

如何對Url中的非法字符進行編碼

  URL編碼也叫percent-encoding(百分號編碼),之所以叫百分號編碼,是因為它的編碼方式非常簡單,使用%加上兩位的字符(012345678ABCDEF)代表一個字節的十六進制形式。URL 編碼默認使用的字符集是US-ASCII。例如a在US-ASCII碼中對應的字節是0x61,那么URL編碼后得到的就是%61。我們在地址欄上輸入http://g.cn/search?q=%61%62%63,實際上就等同於在google上搜索abc了。又如@符號在ASCII字符集中對應的字節為0x40,經過Url編碼之后得到的是%40。

  對於非ASCII字符,需要使用ASCII字符集的超集進行編碼得到相應的字節,然后對每個字節執行百分號編碼。對於Unicode字符,RFC文檔建議使用utf-8對其進行編碼得到相應的字節,然后對每個字節執行百分號編碼。如"中文"使用UTF-8字符集得到的字節為0xE4 0xB8 0xAD 0xE6 0x96 0x87,經過Url編碼之后得到"%E4%B8%AD%E6%96%87"。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM