HTTP必知必會

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

HTTP消息HTTP請求消息HTTP響應消息
消息首行請求行響應行
消息頭部請求頭請求頭
消息正文請求正文響應正文

Web服務器把接收到的HTTP請求消息封裝成request對象,作為service的參數傳入service函數,service函數會被調用多次,每訪問一次Servlet,它的servlet就會被調用一次。

Web服務器收到客戶端的HTTP請求,會針對每一次請求,分別創建一個用于代表請求的request對象、和代表響應的response對象。

request和response對象即代表請求和響應,那我們要獲取客戶機提交過來的數據,只需要找request對象就行了。要向客戶機輸出數據,只需要找response對象就行了。

HTTP協議作為網絡傳輸的基本協議,有著廣泛的應用。HTTP協議的完整內容很多,但是其核心知識卻又簡單精煉。學習者應該掌握其基本結構,并且能夠舉一反三。這篇文章所列的,就是在實際開發中必須知道必須掌握的HTTP知識。

HTTP協議

HTTP協議:消息的分類

HTTP消息(有的文章稱之為報文)分為請求消息響應消息兩種基本分類。其中請求消息是客戶端發送給服務器的用于請求服務資源的消息,響應消息是服務器對請求消息的應答。一般來說,一個響應對應一個請求,不多也不少。

HTTP協議:特點

HTTP協議被人總結為無連接無狀態的特點:

  1. 無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。

  2. 無狀態:HTTP協議是無狀態協議。無狀態是指協議對于事務處理沒有記憶能力。缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

HTTP協議:消息的基本格式

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

  1. 消息首行

  2. 消息頭部(Header)(包括請求頭響應頭

  3. 消息正文(Body)

其中,頭部用來指出HTTP消息的一些屬性,它們有固定的格式;正文部分是傳輸的實際內容,它們的格式是任意的,通常在消息頭部中用Content-Type頭來指定。消息首行在HTTP請求消息和HTTP響應消息中的具體格式略有區別,它們表示的按理說應該是HTTP消息最基本的部分。不論是HTTP請求消息還是HTTP響應消息,消息首行都是有的,否則會出現不可饒恕的解析錯誤;然而消息頭部和消息正文是可選的,不過在實際過程中,多多少少都要包含一些基本的消息頭部。

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

知道的人也許知道,HTTP消息是基于TCP協議的應用層協議。TCP協議是網絡流協議一種。抽象地講,就是從一臺主機一個字節一個字節有序地傳輸到另一臺主機。對于HTTP協議來說,自然保持了這種有序性,即按照消息首行、消息頭部、消息正文的順序進行傳輸。消息首行和消息頭部都是ASCII文本流,正文是字節流。一個特殊的控制結構CRLF用來控制每個部分的結束。

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

下面通過一個例子來解釋CRLF在HTTP請求消息中的控制。

GET?/simple.html?HTTP/1.1<CRLF>?????-----?HTTP請求消息的消息首行:請求行
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>??????????????????????????????-----?空白行表示頭部的結束-----?接下來的內容是消息正文的部分

這是一個簡單的HTTP請求消息。我在其中做了一些必要的刪減,以便每個頭足夠短都能在一行中顯示。記住消息首行消息頭部ASCII流消息正文字節流,它們在消息實體中是連續的片段并不像代碼中所示那樣有換行的結構。換句話說,原始的消息應該是如下形式:

GET?/simple.html?HTTP/1.1
<CRLF>       // 這一行是HTTP請求消息的消息首行:請求行
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>

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

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

HTTP請求消息

接下來具體講講HTTP請求消息。誠心而論,光是寫上面這么點內容就花費了我好久。每每想到寫博客耗費的精力和時間,都會影響到我寫博客的動力。

之前已經說過,HTTP請求消息也分為三個部分:

  1. 請求行(屬于消息首行)

  2. 請求頭(屬于消息頭部)

  3. 請求正文(屬于消息正文)

其中請求頭的格式我們已經見過。請求行的基本格式為:

方法?路徑?版本

例如下面的具體例子:

GET?/simple.html?HTTP/1.1

就有對應關系:

  • 方法:GET

  • 路徑:/simple.html

  • 版本:HTTP/1.1

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

HTTP請求:方法

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

  1. GET

  2. POST

  3. PUT

  4. PATCH

  5. DELETE

  6. HEAD

  7. OPTIONS

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

再比如,GET方法的請求消息是不能定義消息體的,HEAD方法的請求其響應消息是不包含消息體的,這些都是HTTP協議對于HTTP方法的約束。

HTTP請求:路徑

方法和路徑的組合構成WEB API的入口,路徑也是很關鍵的。路徑的基本格式一般是:

basic-path[?query-string]

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

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

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

在這里,&分隔不同的鍵值對,=表示的關系。可以看到一共有四個鍵值對關系,它們是:

  • k1: v1

  • k2: v2

  • k3: 空字符串

  • k4: 起碼該鍵被定義了

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

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

在實際的HTTP請求消息中,對于如下的鍵值關系

k1:?&k2:?=

具體的query-string要寫成:

k1=%26&k2=%3D

這是因為在ASCII編碼中,&的16進制表示是26=的16進制表示是3D。對于需要的編碼,就要表示成其實際編碼的16進制表示,每個字節都用一個%XX三個字符進行表示。這樣,%本身也就要進行編碼了,它的編碼是%25。除了這些控制字符的編碼,還可以進行中文等非英語語言的編碼。

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

關于URL編碼

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

HTTP請求消息消息頭部

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

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

在小節的末尾,我良心地給出一個關于HTTP預定義頭的參考網址:

HTTP消息頭大全

HTTP響應消息

HTTP響應消息的基本格式也是一樣的,包含三個部分:

  1. 響應行(屬于首行)

  2. 響應頭(屬于頭部)

  3. 響應正文(屬于正文)

響應頭部響應正文我覺得不需要再多說了。

需要注意的是:當一個瀏覽器給服務器發送請求后,無論服務器頁面有沒有out.println()方法中有沒有要打印的東西,HTTP響應消息都會返回,只不過是響應的內容是空的。

響應行的基本格式是:

版本號?狀態碼?狀態文本

例如下面的響應行:

HTTP/1.1?200?OK

其對應關系為:

  • 版本號:HTTP/1.1

  • 狀態碼:200

  • 狀態文本:OK

HTTP狀態碼主要表示應答的狀態。狀態碼是由3個數字表示,其中第一個數字表示一個大狀態,后面兩個數字表示該大狀態的一個子狀態。200就表示操作成功,還有其他常見的如403表示不能瀏覽目錄,404表示對象未找到,500表示服務器錯誤等等。

狀態碼一共分為五個大狀態,它們是:

  • 1xx

  • 2xx:請求成功處理

  • 3xx

  • 4xx:客戶端出錯

  • 5xx:服務器端出錯

HTTP狀態碼大全

HTTP協議示例

接下來的所有示例中,我們將代碼都寫成前面的一行一行的模式,但略去。這時只要記住每行的結尾都暗含一個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請求沒有請求正文,但可以包含query-string。

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

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

一個返回404錯誤的響應示例:

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>

?

轉載于:https://my.oschina.net/wangsifangyuan/blog/650991

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458902.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458902.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458902.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

float數據在計算機內存中的存儲方法

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 浮點型變量在計算機內存中占用4字節&#xff08;Byte&#xff09;,即32-bit。遵循IEEE…

Geometric Shapes - POJ 3449(多邊形相交)

題目大意&#xff1a;給一些幾何圖形的編號&#xff0c;求出來這些圖形都和那些相交。分析&#xff1a;輸入的正方形對角線上的兩個點&#xff0c;所以需要求出來另外兩個點&#xff0c;公式是&#xff1a;x2:(x1x3y3-y1)/2; y2:(y1y3x1-x3)/2;x4:(x1x3-y3y1)/2; y4:(y1y3-x1x3…

更新10_linux,時隔十年,QQ更新了Linux版本

昨天1024程序員節&#xff0c;QQ悄悄地更新了QQ for Linux&#xff0c;也許是給各位一個驚喜吧。官網及其的簡陋。和一個Word文檔似的。十年一更&#xff0c;有網友稱&#xff0c;瞬間回到QQ2006&#xff0c;確實界面功能有些落后&#xff0c;相信QQ可以跟上潮流的&#xff0c;…

[滲透測試]掃目錄,Sqlmap利用均超時,利用dirb掃描

今天碰到一個網友傳來的Webshell地址&#xff0c;問我對方如何取得webshell。 網站為阿里云服務器&#xff0c;存在明顯的注入漏洞&#xff0c;但是任何語句都會令網頁報錯&#xff0c;sqlmap一直超時&#xff0c;御劍掃描目錄1個線程也會導致被屏蔽IP。 經一學長提點&#xff…

x = x+1,x+=1,x++那個的執行效率高

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** x x1的效率最低 1&#xff09;讀取右邊x的地址 2&#xff09;執行x13&#xff09;讀…

修正線性單元(Rectified linear unit,ReLU)

修正線性單元&#xff08;Rectified linear unit&#xff0c;ReLU&#xff09; Rectified linear unit 在神經網絡中&#xff0c;常用到的激活函數有sigmoid函數f(x)11exp(?x)、雙曲正切函數f(x)tanh(x)&#xff0c;今天要說的是另外一種activation function&#xff0c;recti…

C語言綜合期末作業,內蒙古農業大學2010年期末c語言綜合作業.doc

內蒙古農業大學2010年期末c語言綜合作業綜合練習作業#includeint main(void){int choice,i;void shuai();void ge();void wang();void bing();for(i1;i<5;i){printf("[1]統計字符個數\n");printf("[2]判斷素數\n");printf("[3]求斐波那契數列\n&qu…

鏈表創建、逆置、刪除詳解

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 對鏈表的理解&#xff1a;http://www.nowamagic.net/librarys/veda/detail/2220 #inc…

python與shell的3種交互方式介紹

【目錄】 1.os.system(cmd) 2.os.popen(cmd) 3.利用subprocess模塊 4.subprocessor模塊進階 【概述】 考慮這樣一個問題&#xff0c;有hello.py腳本&#xff0c;輸出”hello, world!”&#xff1b;有testinput.py腳本&#xff0c;等待用戶輸入&#xff0c;然后打印用戶輸入的數…

C語言里if語句變量作為判斷條件,C語言教學(九-上)if else判斷語句

原標題&#xff1a;C語言教學(九-上)if else判斷語句今天講if else判斷語句&#xff0c;簡單理解就是進行條件判斷&#xff0c;如果條件達到則執行if 里或else里的語句。先來看if。if的寫法和for差不多,就是不用括號里的兩個分號&#xff0c;if (條件) { }&#xff0c;if加括號…

const修飾指針和引用的用法【轉貼】

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** const修飾的指針會額外的占內存嗎&#xff1f; 仍然是4&#xff0c;不會占額外的…

調整linux系統時區

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 好吧&#xff0c;使用tzselect又靠譜些&#xff0c;使用前把/etc/localtime刪除了。 執行上前那個告訴我文件重新了&#xff0c;所以就沒有搞了轉載于:https://www.cnblogs.com/hark0623/p/4807426.html

stm32c語言設計以及注釋,13個基于STM32的經典項目設計實例,全套資料~-嵌入式系統-與非網...

STM32單片機現已火遍大江南北&#xff0c;各種教程資料也是遍布各大網站論壇&#xff0c;可謂一抓一大把&#xff0c;但大部分都差不多。今天總結了幾篇電路城上關于STM32 的制作&#xff0c;不能說每篇都是經典&#xff0c;但都是在其他地方找不到的&#xff0c;很有學習參考意…

memcpy,strcpy,strncpy

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** memcpy c和c使用的內存拷貝函數.從源src所指的內存地址的起始位置開始拷貝n個字節…

二維數組聯通子數組和最大

題目要求&#xff1a; 返回一個二維整數數組中最大聯通子數組的和。輸入一個二維整形數組&#xff0c;數組里有正數也有負數。文件輸出。思路:和之前的動態規劃相識&#xff0c;把二維數組轉換為一維數組&#xff0c;先求每一個列的子數組和最大&#xff0c;最后在用正數就加&a…

c語言如何給變量加鎖,C語言互斥鎖-條件變量實現公共緩存區數據讀寫

#include char buffer[128];int has_data0;pthread_mutex_t mutex;pthread_cond_t cond;pthread_cond_t cond2;void read_buf(void){do{pthread_mutex_lock(&mutex);//鎖定互斥鎖if(has_data0){/*阻塞線程,等待另外一個線程發送信號&#xff0c;同時為公共數據區解鎖*/pthr…

view-activity跟控件在onkey事件上的傳遞關系

android 中Activity跟View對于鍵盤的監聽&#xff0c;主要有以下幾個方法 //按鍵按下 public boolean onKeyDown(int keyCode, KeyEvent event) {} //按鍵彈起 public boolean onKeyUp(int keyCode, KeyEvent event) {} //常按 public boolean onKeyLongPress(int keyCode, Ke…

PMP考試的過與不過

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 我在一年多時間里參加了三次PMP考試&#xff0c;前兩次都失敗&#xff0c;直到第三次才…

JPA一對多循環引用的解決

說是解決&#xff0c;其實不是很完美的解決的&#xff0c;寫出來只是想記錄一下這個問題或者看一下有沒有哪位仁兄會的&#xff0c;能否知道一二。 下面說說出現問題&#xff1a; 問題是這樣的&#xff0c;當我查詢一個一對多的實體的時候&#xff0c;工具直接就爆了&#xff0…

太原理工大學c語言課程設計報告,[太原理工大學C語言實驗報告.doc

[太原理工大學C語言實驗報告本科實驗報告課程名稱&#xff1a; 程序設計技術B實驗項目&#xff1a;實驗地點&#xff1a; 明向校區軟件學院機房專業班級&#xff1a; 學號&#xff1a;學生姓名&#xff1a;指導教師&#xff1a; 呼克佑2014年 12月 日實驗名稱 實驗一 C語言的運…