原文地址:https://blog.csdn.net/woaixiaoyu520/article/details/76690686
關(guān)于Content-Type
Content-Type是實(shí)體頭域(或稱為實(shí)體頭部,entity header)用于向接收方指示實(shí)體(entity body)的介質(zhì)類型的,或稱為資源的MIME類型,現(xiàn)在通常稱media type更為合適。(例如,指定HEAD方法送到接收方的實(shí)體介質(zhì)類型,或GET方法發(fā)送的請(qǐng)求介質(zhì)類型,表示后面的文檔屬于什么MIME類型。)
在響應(yīng)中,Content-Type標(biāo)頭告訴客戶端實(shí)際返回的內(nèi)容的內(nèi)容類型。瀏覽器會(huì)在某些情況下進(jìn)行MIME嗅探,并不一定遵循此標(biāo)題的值; 為了防止這種行為,可以將標(biāo)題 X-Content-Type-Options 設(shè)置為 nosniff。
在請(qǐng)求中 (如POST 或 PUT),客戶端告訴服務(wù)器實(shí)際發(fā)送的數(shù)據(jù)類型。
語法
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=something[1 to 70 characters]
media-type 資源或數(shù)據(jù)的 media type
charset 字符編碼標(biāo)準(zhǔn)
boundary 對(duì)于多部分(multipart)實(shí)體,boundary 是必需的,它用于封裝消息的多個(gè)部分的邊界。其由1到70個(gè)字符組成,瀏覽器自動(dòng)生成,該字符集對(duì)于通過網(wǎng)關(guān)魯棒性良好,不以空白結(jié)尾。
例子
Content-Type 在HTML表單中
在通過HTML form提交生成的POST請(qǐng)求中,請(qǐng)求頭的Content-Type由元素上的enctype屬性指定:
<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="description" value="some text">
<input type="file" name="myFile">
<button type="submit">Submit</button>
</form>
請(qǐng)求頭看起來像這樣(在這里省略了一些 headers):
POST /foo HTTP/1.1
Content-Length: 68137
Content-Type: multipart/form-data; boundary=---------------------------974767299852498929531610575
---------------------------974767299852498929531610575
Content-Disposition: form-data; name="description"
some text
---------------------------974767299852498929531610575
Content-Disposition: form-data; name="myFile"; filename="foo.txt"
Content-Type: text/plain
(content of the uploaded file foo.txt)
---------------------------974767299852498929531610575
POST常見數(shù)據(jù)提交類型
HTTP中,提交數(shù)據(jù)的方式,最常用的就是GET和POST。
GET方式,是把參數(shù)按鍵值對(duì)通過QueryString的方式放在URL尾部,比如: http://www.example.com/test.html?a=1&b=2
POST方法,通常是把要提交的表單放在一個(gè)Form中,指明action后就可以提交數(shù)據(jù)
其實(shí)這些都是表象,W3C上對(duì)如何處理表單有明確的過程說明:
When the user submits a form (e.g., by activating a submit button), the user agent processes it as follows.
Step one: Identify the successful controlsStep two: Build a form data set
Step three: Encode the form data set
The form data set is then encoded according to the content type specified by the enctype attribute of the FORM element.Step four: Submit the encoded form data set
Finally, the encoded data is sent to the processing agent designated by the action attribute using the protocol specified by the method attribute.This specification does not specify all valid submission methods or content types that may be used with forms. However, HTML 4 user agents must support the established conventions in the following cases:
- If the method is “get” and the action is an HTTP URI, the user agent takes the value of action, appends a `?’ to it, then appends the form data set, encoded using the “application/x-www-form-urlencoded” content type. The user agent then traverses the link to this URI. In this scenario, form data are restricted to ASCII codes.
- If the method is “post” and the action is an HTTP URI, the user agent conducts an HTTP “post” transaction using the value of the action attribute and a message created according to the content type specified by the enctype attribute.
翻譯過來就是告訴我們,提交數(shù)據(jù)時(shí)需要通過表單enctype屬性(規(guī)定在發(fā)送到服務(wù)器之前應(yīng)該如何對(duì)表單數(shù)據(jù)進(jìn)行編碼)根據(jù)content type進(jìn)行編碼。并且,如果是GET,用”?”連接,編碼方式為“application/x-www-form-urlencoded”;如果是POST則根據(jù)enctype屬性確定content type,默認(rèn)也為”application/x-www-form-urlencoded”。
附enctype取值編碼含義
值 描述 application/x-www-form-urlencoded 在發(fā)送前編碼所有字符 (默認(rèn),空格轉(zhuǎn)換為 “+” 加號(hào),特殊符號(hào)轉(zhuǎn)換為 ASCII HEX 值) multipart/form-data 不對(duì)字符編碼 (在使用包含文件上傳控件的表單時(shí),必須使用該值) text/plain 純文本 (空格轉(zhuǎn)換為 “+” 加號(hào),但不對(duì)特殊字符編碼,據(jù)說get方式會(huì)這樣,post時(shí)不會(huì))
因此,POST請(qǐng)求的消息主體放在entity body中,服務(wù)端根據(jù)請(qǐng)求頭中的Content-Type字段來獲取消息主體的編碼方式,進(jìn)而進(jìn)行解析數(shù)據(jù)。
application/x-www-form-urlencoded
最常見的 POST 提交數(shù)據(jù)的方式,原生Form表單,如果不設(shè)置 enctype 屬性,默認(rèn)為application/x-www-form-urlencoded 方式提交數(shù)據(jù)。請(qǐng)求類似于下面這樣(無關(guān)的請(qǐng)求頭域已略去):
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
name=test&val1=1&val2=%E6%B5%8B%E8%AF%95&val3%5B%5D=2
首先,Content-Type被指定為 application/x-www-form-urlencoded;其次,提交的表單數(shù)據(jù)會(huì)轉(zhuǎn)換為鍵值對(duì)并按照 key1=val1&key2=val2 的方式進(jìn)行編碼,key 和 val 都進(jìn)行了 URL 轉(zhuǎn)碼。大部分服務(wù)端語言都對(duì)這種方式有很好的支持。
另外,如利用AJAX 提交數(shù)據(jù)時(shí),也可使用這種方式。例如 jQuery,Content-Type 默認(rèn)值都是”application/x-www-form-urlencoded;charset=utf-8”。
multipart/form-data
另一個(gè)常見的 POST 數(shù)據(jù)提交的方式, Form 表單的 enctype 設(shè)置為multipart/form-data,它會(huì)將表單的數(shù)據(jù)處理為一條消息,以標(biāo)簽為單元,用分隔符(這就是boundary的作用)分開,類似我們上面Content-Type中的例子。
由于這種方式將數(shù)據(jù)有很多部分,它既可以上傳鍵值對(duì),也可以上傳文件,甚至多個(gè)文件。當(dāng)上傳的字段是文件時(shí),會(huì)有Content-Type來說明文件類型;Content-disposition,用來說明字段的一些信息。每部分都是以 –boundary 開始,緊接著是內(nèi)容描述信息,然后是回車,最后是字段具體內(nèi)容(字段、文本或二進(jìn)制等)。如果傳輸?shù)氖俏募?,還要包含文件名和文件類型信息。消息主體最后以 –boundary– 標(biāo)示結(jié)束。
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
application/json
Content-Type: application/json 作為響應(yīng)頭比較常見。實(shí)際上,現(xiàn)在越來越多的人把它作為請(qǐng)求頭,用來告訴服務(wù)端消息主體是序列化后的 JSON 字符串,其中一個(gè)好處就是JSON 格式支持比鍵值對(duì)復(fù)雜得多的結(jié)構(gòu)化數(shù)據(jù)。由于 JSON 規(guī)范的流行,除了低版本 IE 之外的各大瀏覽器都原生支持JSON.stringify,服務(wù)端語言也都有處理 JSON 的函數(shù),使用起來沒有困難。
Google 的 AngularJS 中的 Ajax 功能,默認(rèn)就是提交 JSON 字符串。例如下面這段代碼:
var data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
...
});
最終發(fā)送的請(qǐng)求是:
POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
text/xml
XML的作用不言而喻,用于傳輸和存儲(chǔ)數(shù)據(jù),它非常適合萬維網(wǎng)傳輸,提供統(tǒng)一的方法來描述和交換獨(dú)立于應(yīng)用程序或供應(yīng)商的結(jié)構(gòu)化數(shù)據(jù),在JSON出現(xiàn)之前是業(yè)界一大標(biāo)準(zhǔn)(當(dāng)然現(xiàn)在也是),相比JSON的優(yōu)缺點(diǎn)大家有興趣可以上網(wǎng)search。因此,在POST提交數(shù)據(jù)時(shí),xml類型也是不可缺少的一種,雖然一般場景上使用JSON可能更輕巧、靈活。
POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>40</i4></value>
</param>
</params>
</methodCall>
XML-RPC就是利用XML編碼,使用HTTP協(xié)議進(jìn)行傳輸?shù)囊环N協(xié)議機(jī)制,它使用的就是這種編碼類型,XML-RPC協(xié)議簡單、功能夠用,各種語言的實(shí)現(xiàn)都有。還有類似的JSON-RPC,不過它可用于在同一進(jìn)程中、套接字或HTTP之間、或其他很多消息傳遞的環(huán)境中傳輸數(shù)據(jù),使用JSON(RFC 4627)作為數(shù)據(jù)格式。
附:
XML-RPC是一個(gè)遠(yuǎn)程過程調(diào)用(遠(yuǎn)端程序呼叫)(remote procedure call,RPC)的分布式計(jì)算協(xié)議,通過XML將調(diào)用函數(shù)封裝,并使用HTTP協(xié)議作為傳送機(jī)制。
以下為一個(gè)尋常的 XML-RPC 請(qǐng)求的范例:
<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>40</i4></value>
</param>
</params>
</methodCall>
相對(duì)于上述請(qǐng)求,以下為一個(gè)尋常回應(yīng)的范例:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>South Dakota</string></value>
</param>
</params>
</methodResponse>
在Chrome瀏覽器的Postman工具中,可以看到后面兩種類型歸為”raw“一類,其可用來上傳任意格式的文本,如Text(text/plain)、JSON(application/json)、XML(application/xml, text/xml)、HTML(text/html)、Javascript(application/javascript)等。
注:application/xml 和 text/xml兩種類型, 二者功能一模一樣,唯一的區(qū)別就是編碼格式,text/xml忽略xml頭所指定編碼格式而默認(rèn)采用us-ascii編碼,而application/xml會(huì)根據(jù)xml頭指定的編碼格式來編碼:
binary (application/octet-stream)
在Chrome瀏覽器的Postman工具中,還可以看到”binary“這一類型,指的就是一些二進(jìn)制文件類型。如application/pdf,指定了特定二進(jìn)制文件的MIME類型。就像對(duì)于text文件類型若沒有特定的子類型(subtype),就使用 text/plain。類似的,二進(jìn)制文件沒有特定或已知的 subtype,即使用 application/octet-stream,這是應(yīng)用程序文件的默認(rèn)值,一般很少直接使用 。
對(duì)于application/octet-stream,只能提交二進(jìn)制,而且只能提交一個(gè)二進(jìn)制,如果提交文件的話,只能提交一個(gè)文件,后臺(tái)接收參數(shù)只能有一個(gè),而且只能是流(或者字節(jié)數(shù)組)。
很多web服務(wù)器使用默認(rèn)的 application/octet-stream 來發(fā)送未知類型。出于一些安全原因,對(duì)于這些資源瀏覽器不允許設(shè)置一些自定義默認(rèn)操作,導(dǎo)致用戶必須存儲(chǔ)到本地以使用。一般來說,設(shè)置正確的MIME類型很重要。
上述介紹了POST的幾種Content-Type,但其中提到了一些所謂HTTP、請(qǐng)求方法、頭域、MIME類型之類的概念,下面就對(duì)其中一些進(jìn)行簡單討論
關(guān)于HTTP
HTTP
HTTP(Hyper Text Transfer Protocol,超文本傳輸協(xié)議)是一個(gè)基于請(qǐng)求與響應(yīng)模式的、無狀態(tài)的、應(yīng)用層的協(xié)議,基于字符(ASCII碼)傳輸,建立在 TCP/IP 協(xié)議之上的應(yīng)用層規(guī)范,HTTP1.1版本中給出一種持續(xù)連接的機(jī)制。規(guī)范把 HTTP 報(bào)文分為四個(gè)部分:請(qǐng)求行/狀態(tài)行、頭域(請(qǐng)求頭部/響應(yīng)頭部)、空行、實(shí)體(請(qǐng)求實(shí)體/響應(yīng)實(shí)體)。結(jié)構(gòu)形如:
請(qǐng)求結(jié)構(gòu)
<Request-Method> <Request-URL> <Http-Version> //請(qǐng)求行(用于請(qǐng)求報(bào)文)
<Headers>
<Entity-Body>
請(qǐng)求實(shí)例
POST /jsswxxSSI/watershed_selectStrongWatershedJson.action HTTP/1.1
Host: 221.226.28.67:88
Connection: keep-alive
Content-Length: 23
Origin: http://221.226.28.67:88
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-Requested-With: XMLHttpRequest
Referer: http://221.226.28.67:88/jsswxxSSI/Web/sq.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=73B0700F86A013721547447A5952F86E
[Form Data ...] //提交的請(qǐng)求數(shù)據(jù)
響應(yīng)結(jié)構(gòu)
<Http-Version> <Status-Code> <Reason-Phrase> //狀態(tài)行(用于響應(yīng)報(bào)文)
<Headers>
<Entity-Body>
響應(yīng)實(shí)例
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 08 Aug 2017 06:33:49 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 300
Connection: keep-alive
Content-Language: zh-CN
[Response Data ...] //接收的響應(yīng)數(shù)據(jù)
HTTP請(qǐng)求方法
根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種請(qǐng)求方法。
HTTP1.0定義了三種請(qǐng)求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了六種請(qǐng)求方法:OPTIONS, PUT, PATCH, DELETE, TRACE 和 CONNECT 方法。
| No. | 方法 | 描述 |
|---|---|---|
| 1 | GET | 請(qǐng)求指定的頁面信息,并返回實(shí)體主體。 |
| 2 | HEAD | 類似于get請(qǐng)求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報(bào)頭 |
| 3 | POST | 向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請(qǐng)求體中。POST請(qǐng)求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改。 |
| 4 | PUT | 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。 |
| 5 | PATCH | 用于對(duì)資源進(jìn)行部分修改。 |
| 6 | DELETE | 請(qǐng)求服務(wù)器刪除指定的頁面。 |
| 7 | CONNECT | HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。 |
| 8 | OPTIONS | 允許客戶端查看服務(wù)器的性能。 |
| 9 | TRACE | 回顯服務(wù)器收到的請(qǐng)求,主要用于測(cè)試或診斷。 |
HTTP響應(yīng)狀態(tài)碼
HTTP狀態(tài)碼(Status-Code)由三個(gè)十進(jìn)制數(shù)字組成,第一個(gè)十進(jìn)制數(shù)字定義了狀態(tài)碼的類型,后兩個(gè)數(shù)字沒有分類的作用。HTTP狀態(tài)碼共分為5種類型:
- 1xx 信息響應(yīng)類,表示接收到請(qǐng)求并且繼續(xù)處理
- 2xx 處理成功響應(yīng)類,表示動(dòng)作被成功接收、理解和接受
- 3xx 重定向響應(yīng)類,為了完成指定的動(dòng)作,必須接受進(jìn)一步處理
- 4xx 客戶端錯(cuò)誤,客戶請(qǐng)求包含語法錯(cuò)誤或者是不能正確執(zhí)行
- 5xx 服務(wù)端錯(cuò)誤,服務(wù)器不能正確執(zhí)行一個(gè)正確的請(qǐng)求
常見狀態(tài)代碼、狀態(tài)描述、說明:
200 OK //客戶端請(qǐng)求成功
400 Bad Request //客戶端請(qǐng)求有語法錯(cuò)誤,不能被服務(wù)器所理解
401 Unauthorized //請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用
403 Forbidden //服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù)
404 Not Found //請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的URL
500 Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤
-
503 Server Unavailable //服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常
更多狀態(tài)碼及說明請(qǐng)參考Status Code and Reason Phrase in W3C
HTTP的頭域
內(nèi)容參考來源于zooyo的博客 HTTP頭部詳解
關(guān)于更多頭域定義可參考Header Field Definitions in W3C
通常HTTP消息包括客戶機(jī)向服務(wù)器的請(qǐng)求消息和服務(wù)器向客戶機(jī)的響應(yīng)消息。這兩種類型的消息由一個(gè)起始行,一個(gè)或者多個(gè)頭域,一個(gè)只是頭域結(jié)束的空行和可選的消息體組成。上面HTTP的介紹里我們已經(jīng)舉過例子。
HTTP的頭域包括通用頭(general header),請(qǐng)求頭(request header),響應(yīng)頭(response header)和實(shí)體頭(entity header)四個(gè)部分。每個(gè)頭域由一個(gè)域名,冒號(hào)(:)和域值三部分組成。域名是大小寫無關(guān)的,域值前可以添加任何數(shù)量的空格符,頭域可以被擴(kuò)展為多行,在每行開始處,使用至少一個(gè)空格或制表符。
通用頭域
通用頭域包含請(qǐng)求和響應(yīng)消息都支持的頭域,通用頭域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。對(duì)通用頭域的擴(kuò)展要求通訊雙方都支持此擴(kuò)展,如果存在不支持的通用頭域,一般將會(huì)作為實(shí)體頭域處理。下面簡單介紹幾個(gè)在UPnP消息中使用的通用頭域。
Cache-Control
Cache -Control指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制。在請(qǐng)求消息或響應(yīng)消息中設(shè)置 Cache-Control并不會(huì)修改另一個(gè)消息處理過程中的緩存處理過程。
請(qǐng)求時(shí)的緩存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,響應(yīng)消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。
各個(gè)消息中的指令含義如下:Public指示響應(yīng)可被任何緩存區(qū)緩存;Private指示對(duì)于單個(gè)用戶的整個(gè)或部分響應(yīng)消息,不能被共享緩存處理。這允許服務(wù)器僅僅描述當(dāng)用戶的部分響應(yīng)消息,此響應(yīng)消息對(duì)于其他用戶的請(qǐng)求無效;no-cache指示請(qǐng)求或響應(yīng)消息不能緩存;no-store用于防止重要的信息被無意的發(fā)布。在請(qǐng)求消息中發(fā)送將使得請(qǐng)求和響應(yīng)消息都不使用緩存;max-age指示客戶機(jī)可以接收生存期不大于指定時(shí)間(以秒為單位)的響應(yīng);min-fresh指示客戶機(jī)可以接收響應(yīng)時(shí)間小于當(dāng)前時(shí)間加上指定時(shí)間的響應(yīng);max-stale指示客戶機(jī)可以接收超出超時(shí)期間的響應(yīng)消息。如果指定max-stale消息的值,那么客戶機(jī)可以接收超出超時(shí)期指定值之內(nèi)的響應(yīng)消息。
Date
date頭域表示消息發(fā)送的時(shí)間,時(shí)間的描述格式由rfc822定義。Date描述的時(shí)間表示世界標(biāo)準(zhǔn)時(shí),換算成本地時(shí)間,需要知道用戶所在的時(shí)區(qū)。例如:
Date:Mon,31 Dec 2001 04:25:57 GMT。
Pragma
Pragma頭域用來包含實(shí)現(xiàn)特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1協(xié)議中,它的含義和Cache- Control:no-cache相同。
注意:由于 Pragma 在 HTTP 響應(yīng)中的行為沒有確切規(guī)范,所以不能可靠替代 HTTP/1.1 中通用首部 Cache-Control,盡管在請(qǐng)求中,假如 Cache-Control 不存在的話,它的行為與 Cache-Control: no-cache 一致。建議只在需要兼容 HTTP/1.0 客戶端的場合下應(yīng)用 Pragma 首部。
Connection
Connection頭域表示連接狀態(tài)。其中:
-
請(qǐng)求:
- close(告訴WEB服務(wù)器或者代理服務(wù)器,在完成本次請(qǐng)求的響應(yīng)后,斷開連接,不要等待本次連接的后續(xù)請(qǐng)求了)。
- keep-alive(告訴WEB服務(wù)器或者代理服務(wù)器,在完成本次請(qǐng)求的響應(yīng)后,保持連接,等待本次連接的后續(xù)請(qǐng)求)。
-
響應(yīng):
- close(連接已經(jīng)關(guān)閉)。
- keep-alive(連接保持著,在等待本次連接的后續(xù)請(qǐng)求)。
Keep-Alive (該特性是非標(biāo)準(zhǔn)的,請(qǐng)盡量不要再生產(chǎn)環(huán)境中使用)
如果瀏覽器請(qǐng)求保持連接,則該頭部可以用來設(shè)置超時(shí)時(shí)長和最大請(qǐng)求數(shù)。例如:
Keep-Alive: timeout=5, max=1000
需要注意的是,把Connection頭域的值設(shè)置為 “keep-alive” 時(shí),這個(gè)首部才有意義。
HTTP 1.0中默認(rèn)是關(guān)閉的,需要在HTTP頭加入”Connection: keep-alive”,才能啟用Keep-Alive;HTTP 1.1中默認(rèn)啟用Keep-Alive,如果加入”Connection: close “,才關(guān)閉;而在HTTP/2 協(xié)議中, Connection 和 Keep-Alive 是被忽略的,其中采用其他機(jī)制來進(jìn)行連接管理。
目前大部分瀏覽器都是用HTTP 1.1協(xié)議,也就是說默認(rèn)都會(huì)發(fā)起Keep-Alive的連接請(qǐng)求了,所以是否能完成一個(gè)完整的Keep-Alive連接就看服務(wù)器設(shè)置情況。
請(qǐng)求頭域
請(qǐng)求頭域允許客戶端向服務(wù)器傳遞關(guān)于請(qǐng)求或者關(guān)于客戶機(jī)的附加信息。
請(qǐng)求頭域可能包含下列字段Accept、Accept-Charset、Accept- Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If- Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、 Proxy-Authorization、Range、Referer、User-Agent。
對(duì)請(qǐng)求頭域的擴(kuò)展要求通訊雙方都支持,如果存在不支持的請(qǐng)求頭域,一般將會(huì)作為實(shí)體頭域處理。
Host:指定請(qǐng)求資源的Intenet主機(jī)和端口號(hào),必須表示請(qǐng)求url的原始服務(wù)器或網(wǎng)關(guān)的位置。HTTP/1.1請(qǐng)求必須包含主機(jī)頭域,否則系統(tǒng)會(huì)以400狀態(tài)碼返回。
Accept:告訴WEB服務(wù)器自己接受什么介質(zhì)類型,/ 表示任何類型,type/* 表示該類型下的所有子類型,type/sub-type。
Accept-Charset: 瀏覽器申明自己接收的字符集。
Authorization:當(dāng)客戶端接收到來自WEB服務(wù)器的 WWW-Authenticate 響應(yīng)時(shí),用該頭部來回應(yīng)自己的身份驗(yàn)證信息給WEB服務(wù)器。
User-Agent:該頭域的內(nèi)容包含發(fā)出請(qǐng)求的用戶信息。
Referer: 該頭域允許客戶端指定請(qǐng)求uri的源資源地址,這可以允許服務(wù)器生成回退鏈表,可用來登陸、優(yōu)化cache等。他也允許廢除的或錯(cuò)誤的連接由于維護(hù)的目的被追蹤。如果請(qǐng)求的URI沒有自己的URI地址,Referer不能被發(fā)送。如果指定的是部分URI地址,則此地址應(yīng)該是一個(gè)相對(duì)地址。
Range:用來告知服務(wù)器請(qǐng)求返回實(shí)體的一個(gè)或者多個(gè)子范圍。在一個(gè) Range 首部中,可以一次性請(qǐng)求多個(gè)部分,服務(wù)器會(huì)以 multipart 文件的形式將其返回。如果服務(wù)器返回的是范圍響應(yīng),需要使用 206 Partial Content 狀態(tài)碼。假如所請(qǐng)求的范圍不合法,那么服務(wù)器會(huì)返回 416 Range Not Satisfiable 狀態(tài)碼,表示客戶端錯(cuò)誤。服務(wù)器允許忽略 Range 首部,從而返回整個(gè)文件,狀態(tài)碼用 200 。例如:
bytes=0-499 //表示頭500個(gè)字節(jié)
bytes=500-999 //表示第二個(gè)500字節(jié)
bytes=-500 //表示最后500個(gè)字節(jié)
bytes=500- //表示500字節(jié)以后的范圍
bytes=0-0,-1 //表示第一個(gè)和最后一個(gè)字節(jié)
bytes=500-600,601-999 //同時(shí)指定幾個(gè)范圍
響應(yīng)頭域
響應(yīng)頭域允許服務(wù)器傳遞不能放在狀態(tài)行的附加信息,這些域主要描述服務(wù)器的信息和 Request-URI進(jìn)一步的信息。
響應(yīng)頭域包含Age、Location、Proxy-Authenticate、Public、Retry- After、Server、Vary、Warning、WWW-Authenticate。
對(duì)響應(yīng)頭域的擴(kuò)展要求通訊雙方都支持,如果存在不支持的響應(yīng)頭 域,一般將會(huì)作為實(shí)體頭域處理。
Location:用于重定向接收者到一個(gè)新URI地址。Location響應(yīng)報(bào)頭域常用在更換域名的時(shí)候。
Server:包含處理請(qǐng)求的原始服務(wù)器的軟件信息。與User-Agent請(qǐng)求報(bào)頭域是相對(duì)應(yīng)的。此域能包含多個(gè)產(chǎn)品標(biāo)識(shí)和注釋,產(chǎn)品標(biāo)識(shí)一般按照重要性排序。
實(shí)體頭域
請(qǐng)求消息和響應(yīng)消息都可以包含實(shí)體信息,實(shí)體信息一般由實(shí)體頭域和實(shí)體組成。引出此篇的Content-Type就屬于實(shí)體頭域。
實(shí)體頭域包含關(guān)于實(shí)體的原信息,包括Allow、Content- Base、Content-Encoding、Content-Language、Content-Length、Content-Location、Content-MD5、Content-Type、 Etag、Expires、Last-Modified、擴(kuò)展頭(extension-header,允許客戶端定義新的實(shí)體頭,但是這些域可能無法被接收方識(shí)別)。
Allow :枚舉資源所支持的 HTTP 方法的集合(如GET、POST等)。
Content-Type:實(shí)體頭用于向接收方指示實(shí)體的介質(zhì)類型。
Content-Encoding:指文檔的編碼(Encode)方法。
Content-Length:表示實(shí)際傳送的字節(jié)數(shù)。
Content-Range:表示傳送的范圍,用于指定整個(gè)實(shí)體中的一部分的插入位置,他也指示了整個(gè)實(shí)體的長度。在服務(wù)器向客戶返回一個(gè)部分響應(yīng),它必須描述響應(yīng)覆蓋的范圍和整個(gè)實(shí)體長度。一般格式:
Content-Range: <unit> <range-start>-<range-end>/<size>
Content-Range: <unit> <range-start>-<range-end>/*
Content-Range: <unit> */<size>
其中:
<unit> 數(shù)據(jù)區(qū)間所采用的單位。通常是字節(jié)(byte)
<range-start> 一個(gè)整數(shù),表示在給定單位下,區(qū)間的起始值
<range-end> 一個(gè)整數(shù),表示在給定單位下,區(qū)間的結(jié)束值
<size> 整個(gè)文件的大?。ㄈ绻笮∥粗?jiǎng)t用"*"表示)
例子:
Content-Range: bytes 200-1000/67589
實(shí)體可以是一個(gè)經(jīng)過編碼的字節(jié)流,它的編碼方式由Content-Encoding或Content-Type定 義,它的長度由Content-Length或Content-Range定義。
關(guān)于MIME類型
MIME類型是一種通知客戶端其接收文件的多樣性的機(jī)制,文件后綴名在網(wǎng)頁上并沒有明確的意義。
因此,使服務(wù)器設(shè)置正確的傳輸類型非常重要,所以正確的MIME類型與每個(gè)文件一同傳輸給服務(wù)器。在網(wǎng)絡(luò)資源進(jìn)行連接時(shí),瀏覽器經(jīng)常使用MIME類型來決定執(zhí)行何種默認(rèn)行為。
語法
type/subtype
MIME的組成結(jié)構(gòu)非常簡單;由類型與子類型兩個(gè)字符串中間用“/”分隔而組成。并不允許空格存在。
type 表示種類分類,可以是獨(dú)立類型(discrete type)或多部分類型(multipart type)。subtype 表示細(xì)分后的每個(gè)類型。
MIME類型對(duì)大小寫不敏感,但是傳統(tǒng)寫法都是小寫。
獨(dú)立類型 (Discrete types)
獨(dú)立類型表明文檔的種類。如下所示:
| 類型 | 描述 | 示例 |
|---|---|---|
| text | 表明文件是普通文本,理論上是可讀的語言 | text/plain, text/html, text/css, text/javascript |
| image | 表明是某種圖像。不包括視頻,但是動(dòng)態(tài)圖(比如動(dòng)態(tài)gif)也使用image類型 | image/gif, image/png, image/jpeg, image/bmp, image/webp |
| audio | 表明是某種音頻文件 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav |
| video | 表明是某種視頻文件 | video/webm, video/ogg |
| application | 表明是某種二進(jìn)制數(shù)據(jù) | application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf |
多部分類型 (Multipart types)
多部分類型表明被分成多個(gè)部分的文檔的類型,通常多個(gè)部分有不同的MIME類型,是對(duì)復(fù)合文檔的一種表現(xiàn)方式。
multipart/form-data 可用于HTML表單從瀏覽器發(fā)送信息給服務(wù)器。
作為多部分文檔格式,它由邊界線(一個(gè)由’–’開始的字符串)劃分出的不同部分組成。每一部分有自己的實(shí)體,以及自己的 HTTP 請(qǐng)求頭,Content-Disposition和 Content-Type 用于文件上傳領(lǐng)域,最常用的 (Content-Length 因?yàn)檫吔缇€作為分隔符而被忽略)。
multipart/byteranges 用于把部分的響應(yīng)報(bào)文發(fā)送回瀏覽器。
當(dāng)發(fā)送狀態(tài)碼 206 Partial Content 時(shí),這個(gè)MIME類型用于指出這個(gè)文件由若干部分組成,每一個(gè)都有其請(qǐng)求范圍。就像其他很多類型Content-Type使用分隔符來制定分界線。每一個(gè)不同的部分都有Content-Type這樣的HTTP頭來說明文件的實(shí)際類型,以及 Content-Range來說明其范圍。
MIME嗅探
在缺失 MIME 類型或客戶端認(rèn)為文件設(shè)置了錯(cuò)誤的 MIME 類型時(shí),瀏覽器可能會(huì)通過查看資源來進(jìn)行MIME嗅探。每一個(gè)瀏覽器在不同的情況下會(huì)執(zhí)行不同的操作。因?yàn)檫@個(gè)操作會(huì)有一些安全問題,有的 MIME 類型表示可執(zhí)行內(nèi)容而有些是不可執(zhí)行內(nèi)容。瀏覽器可以通過請(qǐng)求頭 Content-Type 來設(shè)置 X-Content-Type-Options 以阻止MIME嗅探。
這一篇就整理到這里,從最初問題POST方法的提交數(shù)據(jù)類型出發(fā),已經(jīng)偏了很多了,后續(xù)有需要再整理其他知識(shí)點(diǎn)吧。