日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

HTTP必知必会

發(fā)布時(shí)間:2023/12/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HTTP必知必会 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

HTTP消息HTTP請(qǐng)求消息HTTP響應(yīng)消息
消息首行請(qǐng)求行響應(yīng)行
消息頭部請(qǐng)求頭請(qǐng)求頭
消息正文請(qǐng)求正文響應(yīng)正文

Web服務(wù)器把接收到的HTTP請(qǐng)求消息封裝成request對(duì)象,作為service的參數(shù)傳入service函數(shù),service函數(shù)會(huì)被調(diào)用多次,每訪問一次Servlet,它的servlet就會(huì)被調(diào)用一次。

Web服務(wù)器收到客戶端的HTTP請(qǐng)求,會(huì)針對(duì)每一次請(qǐng)求,分別創(chuàng)建一個(gè)用于代表請(qǐng)求的request對(duì)象、和代表響應(yīng)的response對(duì)象。

request和response對(duì)象即代表請(qǐng)求和響應(yīng),那我們要獲取客戶機(jī)提交過來的數(shù)據(jù),只需要找request對(duì)象就行了。要向客戶機(jī)輸出數(shù)據(jù),只需要找response對(duì)象就行了。

HTTP協(xié)議作為網(wǎng)絡(luò)傳輸?shù)幕緟f(xié)議,有著廣泛的應(yīng)用。HTTP協(xié)議的完整內(nèi)容很多,但是其核心知識(shí)卻又簡(jiǎn)單精煉。學(xué)習(xí)者應(yīng)該掌握其基本結(jié)構(gòu),并且能夠舉一反三。這篇文章所列的,就是在實(shí)際開發(fā)中必須知道必須掌握的HTTP知識(shí)。

HTTP協(xié)議

HTTP協(xié)議:消息的分類

HTTP消息(有的文章稱之為報(bào)文)分為請(qǐng)求消息響應(yīng)消息兩種基本分類。其中請(qǐng)求消息是客戶端發(fā)送給服務(wù)器的用于請(qǐng)求服務(wù)資源的消息,響應(yīng)消息是服務(wù)器對(duì)請(qǐng)求消息的應(yīng)答。一般來說,一個(gè)響應(yīng)對(duì)應(yīng)一個(gè)請(qǐng)求,不多也不少。

HTTP協(xié)議:特點(diǎn)

HTTP協(xié)議被人總結(jié)為無連接、無狀態(tài)的特點(diǎn):

  • 無連接:無連接的含義是限制每次連接只處理一個(gè)請(qǐng)求。服務(wù)器處理完客戶的請(qǐng)求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時(shí)間。

  • 無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。

  • HTTP協(xié)議:消息的基本格式

    HTTP協(xié)議的請(qǐng)求消息和響應(yīng)消息的格式及其相似。提煉出它們的共性,可以指出,HTTP消息(包括HTTP請(qǐng)求消息、HTTP響應(yīng)消息)分為三個(gè)部分:

  • 消息首行

  • 消息頭部(Header)(包括請(qǐng)求頭響應(yīng)頭

  • 消息正文(Body)

  • 其中,頭部用來指出HTTP消息的一些屬性,它們有固定的格式;正文部分是傳輸?shù)?span style="color:rgb(255,0,0);">實(shí)際內(nèi)容,它們的格式是任意的,通常在消息頭部中用Content-Type頭來指定。消息首行在HTTP請(qǐng)求消息和HTTP響應(yīng)消息中的具體格式略有區(qū)別,它們表示的按理說應(yīng)該是HTTP消息最基本的部分。不論是HTTP請(qǐng)求消息還是HTTP響應(yīng)消息,消息首行都是有的,否則會(huì)出現(xiàn)不可饒恕的解析錯(cuò)誤;然而消息頭部和消息正文是可選的,不過在實(shí)際過程中,多多少少都要包含一些基本的消息頭部。

    HTTP消息主要是基于ASCII編碼的消息實(shí)體。主要的意思是指消息首行和消息頭部都是以ASCII編碼,而消息正文部分的編碼就顯得任意了。在實(shí)際的開發(fā)中,發(fā)送的文本消息時(shí)常會(huì)碰到亂碼的問題。一種解決辦法是,對(duì)于文本消息,約定以UTF-8格式進(jìn)行編碼解碼

    知道的人也許知道,HTTP消息是基于TCP協(xié)議的應(yīng)用層協(xié)議。TCP協(xié)議是網(wǎng)絡(luò)流協(xié)議一種。抽象地講,就是從一臺(tái)主機(jī)一個(gè)字節(jié)一個(gè)字節(jié)有序地傳輸?shù)搅硪慌_(tái)主機(jī)。對(duì)于HTTP協(xié)議來說,自然保持了這種有序性,即按照消息首行、消息頭部、消息正文的順序進(jìn)行傳輸。消息首行和消息頭部都是ASCII文本流,正文是字節(jié)流。一個(gè)特殊的控制結(jié)構(gòu)CRLF用來控制每個(gè)部分的結(jié)束。

    CRLF是回車符和換行符的意思,它們是兩個(gè)特殊的ASCII字符。CR是回車符(\r),在ASCII中的編碼是13;LF是換行符(\n),在ASCII中的編碼是10.

    下面通過一個(gè)例子來解釋CRLF在HTTP請(qǐng)求消息中的控制。

    GET?/simple.html?HTTP/1.1<CRLF>?????-----?HTTP請(qǐng)求消息的消息首行:請(qǐng)求行 Accept:?text/html<CRLF>?????????????--| Accept-Language:?zh-cn<CRLF>??????????| Accept-Encoding:?gzip,?deflate<CRLF>??|--?消息頭部 User-Agent:?Mozilla/4.0<CRLF>?????????| Host:?localhost:8080<CRLF>????????????| Connection:?Keep-Alive<CRLF>????????--| <CRLF>??????????????????????????????-----?空白行表示頭部的結(jié)束-----?接下來的內(nèi)容是消息正文的部分

    這是一個(gè)簡(jiǎn)單的HTTP請(qǐng)求消息。我在其中做了一些必要的刪減,以便每個(gè)頭足夠短都能在一行中顯示。記住消息首行消息頭部ASCII流消息正文字節(jié)流,它們?cè)?span style="color:rgb(255,0,0);">消息實(shí)體中是連續(xù)的片段并不像代碼中所示那樣有換行的結(jié)構(gòu)。換句話說,原始的消息應(yīng)該是如下形式:

    GET?/simple.html?HTTP/1.1 <CRLF> // 這一行是HTTP請(qǐng)求消息的消息首行:請(qǐng)求行 Accept:?text/html <CRLF> Accept-Language:?zh-cn <CRLF> Accept-Encoding:?gzip,?deflate <CRLF> User-Agent:?Mozilla/4.0 <CRLF> Host:?localhost:8080 <CRLF> Connection:?Keep-Alive <CRLF> <CRLF>

    回到之前有換行符的代碼例子中去。將每個(gè)CRLF單獨(dú)列為一行是為了便于觀察組織。可以清楚地看到,第一行是請(qǐng)求行,以CRLF標(biāo)志其結(jié)束;接下來是頭部,含有多個(gè)消息頭,每行定義一個(gè)消息頭,以CRLF標(biāo)志其結(jié)束;一個(gè)單獨(dú)的CRLF(緊接著上一個(gè)CRLF)表示整個(gè)頭部的結(jié)束,接下來是正文部分。在 這個(gè)示例中,正文部分為空。

    另外,可以看到每個(gè)HTTP消息的消息頭部的格式都是一致的,即Key:Value的形式。其中Key表示消息頭部,Value表示消息頭部

    HTTP請(qǐng)求消息

    接下來具體講講HTTP請(qǐng)求消息。誠(chéng)心而論,光是寫上面這么點(diǎn)內(nèi)容就花費(fèi)了我好久。每每想到寫博客耗費(fèi)的精力和時(shí)間,都會(huì)影響到我寫博客的動(dòng)力。

    之前已經(jīng)說過,HTTP請(qǐng)求消息也分為三個(gè)部分:

  • 請(qǐng)求行(屬于消息首行)

  • 請(qǐng)求頭(屬于消息頭部)

  • 請(qǐng)求正文(屬于消息正文)

  • 其中請(qǐng)求頭的格式我們已經(jīng)見過。請(qǐng)求行的基本格式為:

    方法?路徑?版本

    例如下面的具體例子:

    GET?/simple.html?HTTP/1.1

    就有對(duì)應(yīng)關(guān)系:

    • 方法:GET

    • 路徑:/simple.html

    • 版本:HTTP/1.1

    請(qǐng)求行是HTTP請(qǐng)求消息的最基本要素。版本是用來聲明HTTP消息的解析規(guī)則,不同的版本在某些地方的表現(xiàn)是不同的,這里不作過多拆解了。現(xiàn)在實(shí)際應(yīng)用中最新的HTTP協(xié)議版本就是HTTP/1.1。路徑可以理解成該請(qǐng)求消息發(fā)往服務(wù)器的入口,一般來講,同一個(gè)路徑應(yīng)該代表同一個(gè)資源實(shí)體。方法表示對(duì)該資源實(shí)體進(jìn)行的操作,例如上述的GET方法,其含義就是請(qǐng)求獲取該資源的內(nèi)容。這些都是通常的解釋,但不是必然的要求。實(shí)際上,服務(wù)器會(huì)解析方法路徑,根據(jù)方法和路徑做出自己相應(yīng)的響應(yīng)。這種響應(yīng)的規(guī)則,可以遵循某些規(guī)范,也可以完全不考慮這些規(guī)范,是任意的。市面上已經(jīng)存在一些約定俗成的規(guī)范了,比如Restful。Restful是非常優(yōu)秀的基于HTTP協(xié)議的WEB API設(shè)計(jì)理念,很值得講,但在這里就不講了。

    HTTP請(qǐng)求:方法

    首先列出最常用的HTTP方法:

  • GET

  • POST

  • PUT

  • PATCH

  • DELETE

  • HEAD

  • OPTIONS

  • 之前說過,服務(wù)器對(duì)于方法的處理,是沒有強(qiáng)制的規(guī)范的。這句話說得并不全對(duì)。其實(shí)每個(gè)HTTP方法,都是有一些HTTP協(xié)議要求的。比如說GET方法請(qǐng)求的資源,瀏覽器端一般都會(huì)有緩存,下次請(qǐng)求的時(shí)候可能從緩存中去取就夠了,服務(wù)器不用再重復(fù)發(fā)送相同的資源了;但是服務(wù)器如果將獲取資源的接口的方法定義為POST,那么瀏覽器端就不會(huì)再對(duì)資源進(jìn)行緩存了,即使每次取到的都是同樣地內(nèi)容,都會(huì)請(qǐng)求服務(wù)器重新發(fā)送一遍。所以說,將請(qǐng)求資源的接口方法定義為POST而不是GET,就是一種不合理的設(shè)計(jì)。

    再比如,GET方法的請(qǐng)求消息是不能定義消息體的,HEAD方法的請(qǐng)求其響應(yīng)消息是不包含消息體的,這些都是HTTP協(xié)議對(duì)于HTTP方法的約束。

    HTTP請(qǐng)求:路徑

    方法和路徑的組合構(gòu)成WEB API的入口,路徑也是很關(guān)鍵的。路徑的基本格式一般是:

    basic-path[?query-string]

    其中[]中的內(nèi)容表示可選的。在上例中,basic-path就是/simple.html,但不包含query-string的內(nèi)容。basic-path形式很像UNIX中絕對(duì)路徑的樣式,要以/打頭。單獨(dú)的/表示一種路徑,/a、/a/b、/a/b/c都是合理的路徑表示。不推薦使用/a/、/a/b/、/a/b/c/這樣/后面不跟任何其他內(nèi)容的形式(/除外)。優(yōu)秀的API設(shè)計(jì)者會(huì)利用不同的路徑層級(jí)來合理地組織資源。

    問號(hào)后面的部分就是query-string。它的格式是任意的,只要客戶端和服務(wù)器約定好一定的形式即可。這個(gè)部分一般是請(qǐng)求參數(shù)的附加。之前說過,GET方法是不包含請(qǐng)求體的,所以GET方法的HTTP請(qǐng)求想要附加參數(shù)只能使用這種方式。當(dāng)然其他方法也是可以使用這種方式附加參數(shù),只要服務(wù)器同意就可以了。query-string的格式任意,但在客戶端和服務(wù)器之間也有預(yù)先定好的約定,即鍵值對(duì)的形式。query-string可以表示成一系 列鍵值對(duì)的集合,用以下方式表示:

    k1=v1&k2=v2&k3=&k4

    在這里,&分隔不同的鍵值對(duì),=表示的關(guān)系。可以看到一共有四個(gè)鍵值對(duì)關(guān)系,它們是:

    • k1: v1

    • k2: v2

    • k3: 空字符串

    • k4: 起碼該鍵被定義了

    一般來說,鍵值對(duì)要寫成k=v的形式,但是k=和僅僅一個(gè)k都是允許的,前者表示鍵k的值是空字符串,后者表示k被定義了,但是其值是什么并不關(guān)心。

    從上面的例子中發(fā)現(xiàn),在query-string中&和=被用于特殊的用途了,我們不能再在其中從容地使用這兩個(gè)符號(hào)了。如果我們要在值中包含這兩個(gè)符號(hào),那咋辦呢?方法就是,編碼。

    在實(shí)際的HTTP請(qǐng)求消息中,對(duì)于如下的鍵值關(guān)系

    k1:?&k2:?=

    具體的query-string要寫成:

    k1=%26&k2=%3D

    這是因?yàn)樵贏SCII編碼中,&的16進(jìn)制表示是26,=的16進(jìn)制表示是3D。對(duì)于需要的編碼,就要表示成其實(shí)際編碼的16進(jìn)制表示,每個(gè)字節(jié)都用一個(gè)%XX三個(gè)字符進(jìn)行表示。這樣,%本身也就要進(jìn)行編碼了,它的編碼是%25。除了這些控制字符的編碼,還可以進(jìn)行中文等非英語(yǔ)語(yǔ)言的編碼。

    對(duì)于編碼部分,我推薦阮一峰的一篇博文:

    關(guān)于URL編碼

    雖然看了也未必懂了,但是最起碼知道編碼不是一件簡(jiǎn)單的事情。

    HTTP請(qǐng)求消息消息頭部

    HTTP請(qǐng)求消息消息頭部格式與之前所說的消息頭格式?jīng)]什么兩樣,就是以冒號(hào)分隔的鍵值對(duì)。HTTP請(qǐng)求消息的請(qǐng)求頭中,既包含預(yù)定義頭(如Content- Type、Content-Length等),也支持自定義頭。原本打算多列出幾個(gè)常見的請(qǐng)求頭的,但限于精力,不打算這樣做了。我只說說我最常用的Content-Type頭吧。

    Content-Type頭,既可用于HTTP請(qǐng)求消息,也可用于HTTP響應(yīng)消息,是規(guī)定請(qǐng)求正文內(nèi)容格式的頭部。例如利用這個(gè)頭部,我們可以規(guī)定正文格式為純文本格式、表單格式、XML格式、JSON格式、圖像格式等。例如Content-Type: application/json就表示JSON文本格式。

    在小節(jié)的末尾,我良心地給出一個(gè)關(guān)于HTTP預(yù)定義頭的參考網(wǎng)址:

    HTTP消息頭大全

    HTTP響應(yīng)消息

    HTTP響應(yīng)消息的基本格式也是一樣的,包含三個(gè)部分:

  • 響應(yīng)行(屬于首行)

  • 響應(yīng)頭(屬于頭部)

  • 響應(yīng)正文(屬于正文)

  • 響應(yīng)頭部響應(yīng)正文我覺得不需要再多說了。

    需要注意的是:當(dāng)一個(gè)瀏覽器給服務(wù)器發(fā)送請(qǐng)求后,無論服務(wù)器頁(yè)面有沒有out.println()方法中有沒有要打印的東西,HTTP響應(yīng)消息都會(huì)返回,只不過是響應(yīng)的內(nèi)容是空的。

    響應(yīng)行的基本格式是:

    版本號(hào)?狀態(tài)碼?狀態(tài)文本

    例如下面的響應(yīng)行:

    HTTP/1.1?200?OK

    其對(duì)應(yīng)關(guān)系為:

    • 版本號(hào):HTTP/1.1

    • 狀態(tài)碼:200

    • 狀態(tài)文本:OK

    HTTP狀態(tài)碼主要表示應(yīng)答的狀態(tài)。狀態(tài)碼是由3個(gè)數(shù)字表示,其中第一個(gè)數(shù)字表示一個(gè)大狀態(tài),后面兩個(gè)數(shù)字表示該大狀態(tài)的一個(gè)子狀態(tài)。200就表示操作成功,還有其他常見的如403表示不能瀏覽目錄,404表示對(duì)象未找到,500表示服務(wù)器錯(cuò)誤等等。

    狀態(tài)碼一共分為五個(gè)大狀態(tài),它們是:

    • 1xx

    • 2xx:請(qǐng)求成功處理

    • 3xx

    • 4xx:客戶端出錯(cuò)

    • 5xx:服務(wù)器端出錯(cuò)

    HTTP狀態(tài)碼大全

    HTTP協(xié)議示例

    接下來的所有示例中,我們將代碼都寫成前面的一行一行的模式,但略去。這時(shí)只要記住每行的結(jié)尾都暗含一個(gè)CRLF控制就可以了。例如:

    GET?/simple.html?bg=white?HTTP/1.1 Accept:?text/html Accept-Language:?zh-cn Accept-Encoding:?gzip,?deflate User-Agent:?Mozilla/4.0 Host:?localhost:8080 Connection:?Keep-Alive

    GET請(qǐng)求沒有請(qǐng)求正文,但可以包含query-string。

    POST請(qǐng)求可以包含請(qǐng)求正文,例如下面帶JSON格式正文的POST請(qǐng)求:

    POST?/test/demo_form.asp?HTTP/1.1 Host:?w3schools.com Content-Type:?application/json Content-Length:?38{"name1":?"value1",?"name2":?"value2"}

    一個(gè)返回404錯(cuò)誤的響應(yīng)示例:

    HTTP/1.1?404?Not?Found Date:?Mon,?06?Mar?2006?09:03:14?GMT Server:?Apache/2.0.55?(Unix)?PHP/5.0.5 Content-Length:?291 Keep-Alive:?timeout=15,?max=100 Connection:?Keep-Alive Content-Type:?text/html;? charset=iso-8859-1? <!DOCTYPE?HTML?PUBLIC?"-//IETF//DTD?HTML?2.0//EN"> <html><head><title>404?Not?Found</title></head><body><h1>Not?Found</h1><p>The?requested?URL?/notexist?was?not?found?on?this?server.</p><hr><address>Apache/2.0.55?(Unix)?PHP/5.0.5?Server?at?localhost?Port?8080</address></body> </html>

    ?

    轉(zhuǎn)載于:https://my.oschina.net/wangsifangyuan/blog/650991

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的HTTP必知必会的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。