溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

前端01.http協(xié)議回顧

發(fā)布時間:2020-07-10 18:00:52 來源:網(wǎng)絡 閱讀:1052 作者:蘇浩智 欄目:建站服務器

一、http1.0和1.1之間有什么區(qū)別?

http1.0 :每一次請求/響應都會建立并關閉一次連接,相應速度慢。

http1.1:在同一個tcp連接中,可以傳輸多個響應或請求。http1.1默認還開啟長連接。

二、客戶端請求。

GET / HTTP/1.1 #動作和http協(xié)議的版本號 

Host: www.test.com:8088  #客戶端訪問的主機地址

Connection: keep-alive  #長連接

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,p_w_picpath/webp,*/*;q=0.8  #當前瀏覽器所能解析的數(shù)據(jù)類型

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36  #客戶端的操作系統(tǒng)以及瀏覽器等信息。

Accept-Encoding: gzip, deflate, sdch  #瀏覽器用來告訴服務器,自己支持的編碼類型。

Accept-Language: zh-CN,zh;q=0.8 #瀏覽器當前的語言信息。

客戶端請求頭,大概分為四部分:

請求首行;  #請求方式 請求路徑 協(xié)議和版本,例如:GET /index.html HTTP/1.1

請求頭信息;# 請求頭名稱:請求頭內(nèi)容,即為key:value格式,例如:Host:localhost

空行;     #用來與請求體分隔開

請求體。   # GET沒有請求體,只有POST有請求體。

GET請求

特點

http默認的請求方式為get。

get請求沒有任何請求體。

一個get請求,大小一定在1k之內(nèi)。

get請求的內(nèi)容,會暴露在地址欄中。

產(chǎn)生get請求的操作:

在瀏覽器地址欄中輸入一個URL,這一定會是個get請求。

點擊頁面上的一個連接,也會是一個get請求。

提交表單,默認情況下是get,可以設置為post。

下面是一個瀏覽器去訪問百度搜索時,產(chǎn)生的請求頭信息:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,p_w_picpath/webp,*/*;q=0.8

#瀏覽器用來告訴服務器,自己這里可以解析的文檔類型,其實這里包含了*/*,就表示什么都可以接收。

Accept-Encoding:gzip, deflate, sdch

#支持的壓縮格式。數(shù)據(jù)在網(wǎng)絡上傳遞時,可能服務器會把數(shù)據(jù)壓縮后再發(fā)送

Accept-Language:zh-CN,zh;q=0.8

#當前客戶端支持的語言,可以在瀏覽器的工具選項中找到語言相關信息

Cache-Control:max-age=0

Connection:keep-alive

#瀏覽器告訴服務端支持長鏈接的方式,保持一段時間鏈接,默認為3000ms

Cookie:BAIDUID=7AD83D51481D0BE4DB3250B5273A7A01:FG=1; BIDUPSID=7AD83D51481D0BE4DB3250B5273A7A01; PSTM=1483207633; BCLID=599596736169088288; 

#因為不是第一次訪問這個地址,所以會在請求中把上一次服務器響應中發(fā)送過來的Cookie在請求中一并發(fā)送去過;這個Cookie的名字為BAIDUUID,FG,BIDUPSID.PSTM,BCLID。

#如果對cookie不理解的話,可以先把cookie當成一個字典,這個字典里可以放多組鍵值對,

BDSFRCVID=B9_sJeCGQG04CSbZK5LXuyRgDeKKnW7TH6aP2rQCi3AO4CkVJ2uIEG0Ptf8g0KubaKiaogKK0gOTH65P; H_BDCLCKID_SF=tJAD_CtatD-3ejrnhCTVMt_e2x7-2D62aKD***3n-hcqEp3hQT0MLptVW44tWtntMGrMKn5cWbrRMUbSj4QmDRDuLUue3x4J0K3paDoaWl5nhMJmb67JDMP0-xQia4oy523ion3vQpP-MftuD6-ajjO0DG8sKC62atoLBRjOMJnqD6rnhPF3QJT3KP6-3MbI3b4J5MOtyqkh8hRG2q5JQ-LUyUTUth47JD6Totol0bI5EqAmLPR4y6D0ytoxJpOJ5JbMopvaKJjvjJjvbURvD--g3-Aqtl8EtJAD_CtatD-3ejrnhCTVMt_e2x7-2D62aKDs5DT7-hcqEp3hQT0MLptVW44tWpvtMGrMKn5cWbrRMUbSj4QmDRDuLUue3x4J0K3paDoaWl5nhMJmb67JDMP0-xQia4oy523ion3vQpP-Mftu-n5jHjJ0DNt83e; BD_CK_SAM=1; PSINO=1; BD_UPN=123253; H_PS_645EC=c485lXcS%2F7FBtERrH33%2FHldUI6NyBW8PijQ%2F%2F54A4h75m4RucmVSSJDxXBg; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDSVRTM=0; BD_HOME=0; H_PS_PSSID=1454_21081_21673_20930; __bsi=12503378464846675469_00_815_R_N_6_0303_C02F_N_I_I_0

Host:www.baidu.com

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36

Referer:http://www.baidu.com 

#注意?。eferer這個標記,只有在通過其他url上連接過來之后,才會產(chǎn)生,請求來自哪個頁面,例如你在百度上點擊鏈接到了這里,那么Referer:http://www.baidu.com;如果你是在瀏覽器的地址欄中直接輸入的地址,那么就沒有Referer這個請求頭了。

    2.post請求。

特點:

請求的數(shù)據(jù)不會出現(xiàn)在地址欄中。(提交給服務端的參數(shù),都會被放進請求體。)

數(shù)據(jù)的大小無上限。

有請求體。

當遇到中文會使用url編碼。

在這解釋下什么是url編碼。

我們都知道Http協(xié)議中參數(shù)的傳輸是"key=value"這種簡直對形式的,如果要傳多個參數(shù)就需要用“&”符號對鍵值對進行分割。如"?name1=value1&name2=value2",這樣在服務端在收到這種字符串的時候,會用“&”分割出每一個參數(shù),然后再用“=”來分割出參數(shù)值。

針對“name1=value1&name2=value2”我們來說一下客戶端到服務端的概念上解析過程: 

  上述字符串在計算機中用ASCII嗎表示為: 

  6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532。 

   6E616D6531:name1 

   3D:= 

   76616C756531:value1 

   26:&

   6E616D6532:name2 

   3D:= 

   76616C756532:value2 

   服務端在接收到該數(shù)據(jù)后就可以遍歷該字節(jié)流,首先一個字節(jié)一個字節(jié)的吃,當吃到3D這字節(jié)后,服務端就知道前面吃得字節(jié)表示一個key,再想后吃,如果遇到26,說明從剛才吃的3D到26子節(jié)之間的是上一個key的value,以此類推就可以解析出客戶端傳過來的參數(shù)。

   現(xiàn)在有這樣一個問題,如果我的參數(shù)值中就包含=或&這種特殊字符的時候該怎么辦。 

比如說“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么實際在傳輸過程中就會變成這樣“name1=va&lu=e1”。我們的本意是就只有一個鍵值對,但是服務端會解析成兩個鍵值對,這樣就產(chǎn)生了奇異。

如何解決上述問題帶來的歧義呢?解決的辦法就是對參數(shù)進行URL編碼 

   URL編碼只是簡單的在特殊字符的各個字節(jié)前加上%,例如,我們對上述會產(chǎn)生奇異的字符進行URL編碼后結果:“name1=va%26lu%3D”,這樣服務端會把緊跟在“%”后的字節(jié)當成普通的字節(jié),就是不會把它當成各個參數(shù)或鍵值對的分隔符。

說道了post請求,在補充兩個請求頭的標記:

Content-Type: application/x-www-form-urlencoded:表單的數(shù)據(jù)類型,說明會使用url格式編碼數(shù)據(jù);url編碼的數(shù)據(jù)都是以“%”為前綴,后面跟隨兩位的16進制。

Content-Length:13:請求體的長度,這里表示13個字節(jié)。

三、服務端響應頭。

服務器回復給客戶端的響應報頭大概分為3部分。

響應頭信息,空行,響應體。

Request URL:http://127.0.0.1:8090/login/ 

#客戶端請求的url

Request Method:GET

#客戶端請求的動作

Status Code:200 OK

#返回給客戶端的狀態(tài)碼

Remote Address:127.0.0.1:8090

Response Headers

view source

Content-Type:text/html; charset=utf-8

#服務端當前應答給客戶端的數(shù)據(jù)類型是什么,以及字符編碼

Date:Wed, 26 Oct 2016 06:48:50 GMT

#響應時間

Server:WSGIServer/0.2 CPython/3.5.2

#服務端類型

X-Frame-Options:SAMEORIGIN

#響應體

Request URL:http://127.0.0.1:8090/login/

Request Method:GET

Status Code:200 OK

Remote Address:127.0.0.1:8090

Response Headers

view source

Content-Type:text/html; charset=utf-8

Date:Wed, 26 Oct 2016 06:48:50 GMT

Server:WSGIServer/0.2 CPython/3.5.2

X-Frame-Options:SAMEORIGIN

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

<form action="/login/" method="post">

  用戶名:<input type="text" name="username"/>

  <input type="submit" value="提交"/>

</form>    

</body>

</html>

   

HTTP/1.1 200 OK:響應協(xié)議為HTTP1.1,狀態(tài)碼為200,表示請求成功,OK是對狀態(tài)碼的解釋;

Server:WSGIServer/0.2 CPython/3.5.2:服務器的版本信息;

Content-Type: text/html;charset=UTF-8:響應體使用的編碼為UTF-8;

Content-Length: 724:響應體為724字節(jié);

Set-Cookie: JSESSIONID=C97E2B4C55553EAB46079A4F263435A4; Path=/hello:響應給客戶端的Cookie;

Date: Wed, 25 Sep 2012 04:15:03 GMT:響應的時間,這可能會有8小時的時區(qū)差

關于狀態(tài)碼做一個小的補充:

200,403,404,50x 這些狀態(tài)碼太常見了,在這里不做過多說明,主要說下302和304。

302:地址跳轉,重定向,當響應碼為302時,表示服務器要求瀏覽器重新再發(fā)一個請求,服務器會發(fā)送一個響應頭Location,它指定了新請求的URL地址。

304:假如說,用戶第一次通過瀏覽器向服務器請求一個資源文件比如說一個html文件。

服務器在應答的時候,會加一個Last-Modified的響應頭,這個響應頭說明了這個html文件最后的修改時間,瀏覽器會把這個html文件的內(nèi)容,以及最后的響應時間記錄下來。

當用戶第二次請求這個html文件時,在請求頭中,會包含一個IF-Modified-since的請求頭,這個請求頭對應的值就是,第一次向服務器發(fā)起請求時,服務器通過Last-Modified響應頭發(fā)給客戶端的值,也就是瀏覽器要請求的這個資源文件的最后修改時間。

If-Modified-Since請求頭就是在告訴服務器,我這里瀏覽器緩存的這個文件最后修改時間是否和服務器端這個文件的最后的修改時間相等,如果相等,那么服務端直接就返回304就不用再響應這個文件的內(nèi)容,瀏覽器會把緩存的內(nèi)容直接顯示出來。

而服務器端會獲取If-Modified-Since值,與瀏覽器緩存的文件當前最后修改時間比對,如果相同,服務器會發(fā)響應碼304,表示index.html與瀏覽器上次緩存的相同,無需再次發(fā)送,瀏覽器可以顯示自己的緩存頁面,如果比對不同,那么說明index.html已經(jīng)做了修改,服務器會響應200。

下面是圖解:

四、關于http協(xié)議的一些誤區(qū)糾正。

http這種協(xié)議是一種無狀態(tài)協(xié)議,沒有任何記憶能力,瀏覽器一旦打開了服務器發(fā)來的網(wǎng)頁,那么瀏覽器和服務器之間就沒有任何聯(lián)系了。

其實很多網(wǎng)上商城的購物車功能,都需要借助于Cookie或Session或服務器端API記錄這些信息,請求服務器結算頁面時同時將這些信息提交到服務器。

當你登錄到一個網(wǎng)站時,你的登錄狀態(tài)也是由Cookie或Session來“記憶”的,因為服務器并不知道你是否登錄。

說道這里,可能有人會問,既然http是無狀態(tài)協(xié)議,那么保持的長連接是個什么鬼?

用一句話來說就是,無狀態(tài)不代表HTTP不能保持TCP連接!

從HTTP/1.1起,默認都開啟了Keep-Alive,保持連接特性,簡單地說,當一個網(wǎng)頁打開完成后,客戶端和服務器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網(wǎng)頁,會繼續(xù)使用這一條已經(jīng)建立的連接。

keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。

五、其他一些常見的響應頭補充。

這些頭都會導致瀏覽器不緩存。

Expires: -1;

Cache-Control: no-cache;

Pragma: no-cache;

具有刷新的功能,3秒后自動跳轉到http://www.baidu.com。

#Refresh#: 時間;url=http://www.baidu.com

這些響應頭在html中都是可以自定義的??!

在HTMl頁面中可以使用來指定響應頭,例如在index.html頁面中給出,表示瀏覽器只會顯示index.html頁面3秒,然后自動跳轉到http://www.baidu.com.


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI