? ? http協議有http0.9,http1.0,http1.1和http2三個版本,但是現在瀏覽器使用的是http1.1的標準,本篇文章著重介紹關于http1.1的版本,同時穿插了解一下http2的一些新特性。
一 介紹
? ? 介紹不多說,HTTP是Hyper Text Transfer Protocol(超文本協議),是一個基于TCP/IP的應用層協議,主要用于從web服務器傳輸超文本到本地的瀏覽器的一個傳輸協議,由請求和響應構成,是一個標準的客戶端服務器模型。
? ? 這里簡要的介紹下http和https的區別:https協議是一個承載在SSL+TLS上,基于http和ssl構建的,其與http最大的區別就是其的安全性,而且其使用的是不一樣的連接方式,用的端口也不一樣(443,http是80),另外由于其確保安全性,那么https就需要進行與服務器的還密鑰和確認加密算法的需要,這樣的話跟服務器進行握手的次數就增多,影響性能且繁瑣。
二 http的主要特點
1 支持客戶端/服務器模式
2 簡單快速:客戶端向服務器請求服務的適合,只需要傳輸方法和路徑。請求的常用方法有GET、HEAD、POST。由于每一種http協議都簡單,使得http服務器的程序規模小,則通信速度很快
3 靈活:http允許傳輸任意類型的數據對象,正在傳輸的類型由請求頭部的Content-Type加以標注
4 HTTP 0.9和1.0使用非持續連接:限制每次連接只處理一個請求,服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。HTTP 1.1使用持續連接:不必為每個web對象創建一個新的連接,一個連接可以傳送多個對象(這個關聯到頭部信息的Connection進行控制)
5 http是無狀態協議。無狀態指的是對于事物處理沒有記憶能力,缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。
(無狀態協議:協議的狀態是指下一次傳輸可以“記住”這次傳輸信息的能力。http不會為了下一次連接維護這次連接所傳輸的信息的,為了保證服務器的內存。
舉例:比如客戶獲得一張網頁之后關閉瀏覽器,然后再一次啟動瀏覽器,再登陸該網站,但是服務器并不知道客戶關閉了一次瀏覽器。由于Web服務器要面對很多瀏覽器的并發訪問,為了提高Web服務器對并發訪問的處理能力,在設計HTTP協議時規定Web服務器發送HTTP應答報文和文檔時,不保存發出請求的Web瀏覽器進程的任何狀態信息。這有可能出現一個瀏覽器在短短幾秒之內兩次訪問同一對象時,服務器進程不會因為已經給它發過應答報文而不接受第二期服務請求。由于Web服務器不保存發送請求的Web瀏覽器進程的任何信息,因此HTTP協議屬于無狀態協議(Stateless Protocol)
)
HTTP協議是無狀態的和Connection: keep-alive的區別:
HTTP是一個無狀態的面向連接的協議,無狀態不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協議(無連接)。
從HTTP/1.1起,默認都開啟了Keep-Alive,保持連接特性,簡單地說,當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。
Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。
1.1 版還引入了管道機制(pipelining),即在同一個TCP連接里面,客戶端可以同時發送多個請求。這樣就進一步改進了HTTP協議的效率。
舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個TCP連接里面,先發送A請求,然后等待服務器做出回應,收到后再發出B請求。管道機制則是允許瀏覽器同時發出A請求和B請求,但是服務器還是按照順序,先回應A請求,完成后再回應B請求。
三 工作流程
一次http操作稱之為一次事物,工作過程可分為四步:
1)首先客戶機與服務器需要建立連接。只要點擊某個超鏈接,HTTP工作開始(建立連接)
2)之后,客戶機發送請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號、后邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。(發送請求)
3)服務器接收到請求之后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、后邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。(響應請求)
4)客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務器斷開連接(斷開連接)
上述過程有可能是客戶機經過了代理服務器才到達的web服務器的
由于HTTP是基于傳輸層的TCP/IP協議的,TCP是一個端到端的面向連接的協議。所謂的端到端可以理解為進程到進程之間的通信,故HTTP在開始傳輸之前需建立TCP連接,TCP連接的過程需要所謂的“三次握手”,如圖。連接之后就可以進行傳輸了,HTTP在傳輸完成之間不會斷開TCP連接,在HTTP1.1中(通過Connection頭設置)這是默認的行為
四 URL詳解
URL:統一資源定位符,是URI(統一資源標識符)的一種,用于描述一個網絡上的資源, 基本格式如下:schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
scheme 指定低層使用的協議(例如:http, https, ftp)
host HTTP服務器的IP地址或者域名
“:”后的是端口,默認是80
path:是訪問資源的路徑
“;”后面的是url-params:URL參數,可以用作一個緩存的標識(session id)
query-string:發送給http服務器的數據,也可以說是查詢參數,用&符號分隔
“#”后面的是錨
五 請求消息
5.1 請求的消息格式如下:
1)請求行,如GET /images/logo.gif HTTP/1.1,表示從/images目錄下請求logo.gif這個文件,使用的是get方法,協議版本是http1.1
2)請求頭,如Accept-Language: en
3)空行
4)可選的消息體
請求行和標題必須以回車換行作為結尾,空行中必定只有回車換行
5.2 請求方法
前面三個是http0.9和http1.0協議就已經有的,后面五個是http1.1之后加的
GET:向特定的資源發送請求
POST:向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據包含在請求中,POST請求可能會導致新的資源建立和/或者已有資源的修改
HEAD:向服務器索要與GET請求相一致的響應,但是響應體不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應消息頭中的元信息。該方法常用于測試超鏈接的有效性,是否可以訪問,以及最近是否更新(那么主要 用于響應頭信息的獲取)
PUT:向制定資源位置上傳其最新的內容
OPTIONS:返回服務器針對特定資源所支持的HTTP請求方法。
DELETE:請求服務器刪除Request-URI所標識的資源
TRACE:回顯服務器收到的請求,用于測試或診斷
CONNECT:http1.1協議種預留給能夠將連接改為管道方式的代理服務器
PATCH:用來將局部修改應用于某一資源,添加于規范RFC5789。
總結就是:GET方法用于在服務器中獲取數據,POST方法是在服務器中修改資源數據,PUT是用于上傳數據,DELETE是在服務器中刪除資源,HEAD是獲取響應頭信息
GET和POST的區別:
1)提交的數據位置不同,GET是在URL之后,而POST是在HTTP包的body中
2)GET提交的數據大小有限制,最多有1024字節,主要是瀏覽器對URL的長度有限制,POST提交的數據沒有限制
3)POST較GET安全,因為GET會將一些信息暴露在URL上,對于提交的數據都會顯示在URL上,若頁面可以緩存或者其他人可以訪問,則可從歷史記錄獲取這個用戶賬號密碼什么的資料
4)GET方式需要使用Request.QueryString來取得變量的值,而POST方式通過Request.Form來獲取變量的值。
六 響應消息
客戶端向服務器發送一個請求,服務器以一個狀態行作為響應,響應的內容包括:消息協議的版本、成功或者錯誤編碼、服務器信息、實體元信息以及必要的實體內容。根據響應類別的類別,服務器響應里可以含實體內容,但不是所有的響應都有實體內容。
格式:
http協議版本? 空格? 狀態碼? 空格 Reason-Phrase 回車換行(Reason-Phrase是個簡單的文本描述),如
七 http的狀態響應碼
1XX(信息類): 表示接收到請求并繼續處理
2XX(響應成功):表示動作被成功接收,理解和接收
關注200:表明該請求被成功地完成,所請求的資源發送回客戶端
3XX(重定向):為了完成指定的動作,必須接受進一步處理
關注304:自從上次請求后,請求的網頁未修改過,服務器返回此響應時,不會返回網頁內容,代表上次的文檔已經被緩存了,還可以繼續使用
4XX(客戶端錯誤類):請求包含錯誤語法或不能正確執行
關注404:一個404錯誤表明可連接服務器,但服務器無法取得所請求的網頁,請求資源不存在。eg:輸入了錯誤的URL
5XX(服務器端錯誤類):服務器不能正確執行一個正確的請求
八 頭部信息
8.1? HTTP常見的請求頭
If-Modified-Since:把瀏覽器端緩存頁面的最后修改時間發送到服務器去,服務器會把這個時間與服務器上實際文件的最后修改時間進行對比。如果時間一致,那么返回304,客戶端就直接使用本地緩存文件。如果時間不一致,就會返回200和新的文件內容??蛻舳私拥街?,會丟棄舊文件,把新文件緩存起來,并顯示在瀏覽器中。(這與對比緩存有關,后文會講到,相對的是響應頭的Last-Modified)
If-None-Match:If-None-Match和ETag一起工作,工作原理是在HTTP響應頭中添加ETag信息。 當用戶再次請求該資源時,將在HTTP請求頭中加入If-None-Match信息(ETag的值)。如果服務器驗證資源的ETag沒有改變(該資源沒有更新),將返回一個304狀態告訴客戶端使用本地緩存文件。否則將返回200狀態和新的資源和Etag(這也與對比緩存有關,且優先級高于上面的If-Modified-Since/Last-Modified對)
Cache-Control:指定請求和響應遵循的緩存機制。緩存指令是單向的(響應中出現的緩存指令在請求中未必會出現),且是獨立的(在請求消息或響應消息中設置Cache-Control并不會修改另一個消息處理過程中的緩存處理過程)。請求時的緩存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,響應消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。(請求頭和響應頭中都有,關于強制緩存的)
Cache-Control:Public 客戶端和服務器都可緩存
Cache-Control:Private 客戶端可緩存
Cache-Control:no-cache 需要使用對比緩存來驗證緩存數據
Cache-Control:no-store 所有內容都不會緩存,強制緩存,對比緩存都不會觸發
Cache-Control:max-age 緩存的內容將在 xxx 秒后失效。
Cache-Control:min-fresh 指示客戶機可以接收響應時間小于當前時間加上指定時間的響應。
Cache-Control:max-stale 指示客戶機可以接收超出超時期間的響應消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內的響應消息。
Accept:瀏覽器端可以接受的MIME類型。例如:Accept: text/html 代表瀏覽器可以接受服務器回發的類型為 text/html 也就是我們常說的html文檔
Accept-Encoding:瀏覽器申明自己可接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate)
Accept-Language:瀏覽器申明自己接收的語言。語言跟字符集的區別:中文是語言,中文有多種字符集,比如big5,gb2312,gbk等等
Accept-Charset:瀏覽器可接受的字符集
User-Agent:告訴HTTP服務器,客戶端使用的操作系統和瀏覽器的名稱和版本
Content-Type:例如:Content-Type: application/x-www-form-urlencoded。
Connection:例如:
Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。HTTP 1.1默認進行持久連接。利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點,Servlet需要在應答中發送一個Content-Length頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然后在正式寫出內容之前計算它的大小。
Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉,當客戶端再次發送Request,需要重新建立TCP連接。
Referer:包含一個URL,用戶從該URL代表的頁面出發訪問當前請求的頁面
Host:(發送請求時,該頭域是必需的)主要用于指定被請求資源的Internet主機和端口號,它通常從HTTP URL中提取出來的(http1.1協議種必須包含)
例如: 我們在瀏覽器中輸入:http://www.guet.edu.cn/index.html,瀏覽器發送的請求消息中,就會包含Host請求頭域:Host:http://www.guet.edu.cn,此處使用缺省端口號80,若指定了端口號,則變成:Host:指定端口號
Cookie:最重要的請求頭之一, 將cookie的值發送給HTTP服務器
Content-Length:表示請求消息正文的長度
Authorization:授權信息
8.2? HTTP常見的響應頭
Allow:服務器支持哪些請求方法(如GET、POST等)
Date:表示消息發送的時間,時間的描述格式由rfc822定義。
Expires:指明應該在什么時候認為文檔已經過期,從而不再緩存它,重新從服務器獲取,會更新緩存
P3P:用于跨域設置Cookie, 這樣可以解決iframe跨域訪問cookie的問題
Set-Cookie:非常重要的header, 用于把cookie發送到客戶端瀏覽器,每一個寫入cookie都會生成一個Set-Cookie。
例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
ETag:和If-None-Match 配合使用。
Last-Modified:用于指示資源的最后修改日期和時間。Last-Modified也可用setDateHeader方法來設置。
Content-Type:WEB服務器告訴瀏覽器自己響應的對象的類型和字符集,
例如:Content-Type: text/html;charset=utf-8
Content-Length:指明實體正文的長度,以字節方式存儲的十進制數字來表示
Content-Encoding:WEB服務器表明自己使用了什么壓縮方法(gzip,deflate)壓縮響應中的對象
Content-Range:用于指定整個實體中的一部分的插入位置,他也指示了整個實體的長度
Content-Language:WEB服務器告訴瀏覽器自己響應的對象所用的自然語言
Connection:
例如:Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。
Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉,當客戶端再次發送Request,需要重新建立TCP連接。
Location:用于重定向一個新的位置,包含新的URL地址
Refresh:表示瀏覽器應該在多少時間之后刷新文檔,以秒計
摘抄于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html
九 HTTP緩存機制
WEB緩存(cache)位于Web服務器和客戶端之間。
緩存會根據請求保存輸出內容的副本,例如html頁面,圖片,文件,當下一個請求來到的時候:如果是相同的URL,緩存直接使用副本響應訪問請求,而不是向源服務器再次發送請求。
HTTP協議定義了相關的消息頭來使WEB緩存盡可能好的工作
9.1 緩存的優點
減少相應延遲:因為請求從緩存服務器(離客戶端更近)而不是源服務器被相應,這個過程耗時更少,讓web服務器看上去相應更快。
減少網絡帶寬消耗:當副本被重用時會減低客戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長并更易于管理。
9.2 http報文中跟緩存有關的頭部字段
為了對以下能用到的一些頭部信息能有個大致了解,介紹以下與緩存有關的頭部字段
1. 通用首部字段(就是請求報文和響應報文都能用上的字段)
2. 請求首部字段
3. 響應首部字段
4. 實體首部字段
9.3 緩存方式
緩存實際上就是根據一些策略規則來決定是否使用瀏覽器中的一些存儲的信息,這個緩存信息可以認為是瀏覽器中有存在的一個緩存數據庫(也可以稱為本地緩存)
根據是否需要重新向服務器發起請求來分類,可分為兩大類(強制緩存、對比緩存)
強制類型不需要向服務器發起請求,對比緩存需要向服務器發起請求
9.3.1 強制緩存
已經具有緩存數據的時候,并且緩存時間未過期的話,使用強制緩存
http1.0的強制緩存是有兩個字段來進行,Pragma(表示禁用緩存)和Expires(啟用緩存和定義緩存時間)。同時使用的話,Pragma優先級會較高,但是響應報文中Expires所定義的緩存時間是相對服務器上的時間而言的,如果客戶端上的時間跟服務器上的時間不一致(特別是用戶修改了自己電腦的系統時間),那緩存時間可能就沒啥意義了,為了解決這個問題,http1.1使用的是新字段:Cache-Control(重點掌握,以此為基準)
注意:為了做http協議的向下兼容,你還是可以看到很多網站依舊會帶上這兩個字段,實際上是可拋棄的兩個字段了
Cache-Control
使用方法: "Cache-Control":"cache-directive"
作為請求頭部的時候,cache-directive的可選值有
作為響應首部時,cache-directive 的可選值有:
實際重點關注五個值private、public、no-cache、max-age,no-store,默認為private
private:客戶端可以緩存
public:客戶端和代理服務器都可緩存(前端的同學,可以認為public和private是一樣的)
max-age=xxx:緩存的內容將在 xxx 秒后失效
no-cache:需要使用對比緩存來驗證緩存數據
no-store:所有內容都不會緩存,強制緩存,對比緩存都不會觸發
舉個例子:
圖中Cache-Control僅指定了max-age,所以默認為private,緩存時間為31536000秒(365天)
也就是說,在365天內再次請求這條數據,都會直接獲取緩存數據庫中的數據,直接使用
9.3.2 對比緩存
對比緩存:即需要進行比較判斷是否可以使用緩存。瀏覽器第一次請求數據時,服務器會將緩存標識與數據一起返回給客戶端,客戶端將二者備份至緩存數據庫中。再次請求數據時,客戶端將備份的緩存標識發送給服務器,服務器根據緩存標識進行判斷,判斷成功后,返回304狀態碼,通知客戶端比較成功,可以使用緩存數據
對比緩存解決的問題:緩存時間過期,但是服務器卻沒有更新這個資源,此時客戶端再次請求服務器把這個資源重新發過來的話,很浪費帶寬和時間。對比緩存就是讓服務器知道客戶端現在存有的緩存文件,其實跟自己所有的文件是一致的,讓客戶端直接使用自己緩存的即可,提高了緩存的復用率
對比緩存是根據請求頭部和響應頭部的緩存標識進行判斷的
對比緩存使用的緩存標識字段
Last-Modified? /? If-Modified-Since
Last-Modified:
服務器在響應請求時,告訴瀏覽器資源的最后修改時間。
If-Modified-Since:
再次請求服務器時,通過此字段通知服務器上次請求時,服務器返回的資源最后修改時間。
服務器收到請求后發現有頭If-Modified-Since 則與被請求資源的最后修改時間進行比對。
若資源的最后修改時間大于If-Modified-Since,說明資源又被改動過,則響應整片資源內容,返回狀態碼200;
若資源的最后修改時間小于或等于If-Modified-Since,說明資源無新修改,則響應HTTP 304,告知瀏覽器繼續使用所保存的cache。
Last-Modified 說好卻也不是特別好,因為如果在服務器上,一個資源被修改了,但其實際內容根本沒發生改變,會因為Last-Modified時間匹配不上而返回了整個實體給客戶端(即使客戶端緩存里有個一模一樣的資源)
ETag / If-None-Match(優先級高于Last-Modified? /? If-Modified-Since)
為了解決上述Last-Modified可能存在的不準確的問題,Http1.1還推出了 ETag 實體首部字段。
Etag可以理解成一個服務器用加密算法計算出來的唯一標識符,用來標識一個資源的,在客戶端第一次請求的時候服務器會隨著數據一起傳給客戶端,客戶端會保留該 ETag 字段,并在下一次請求時將其一并帶過去給服務器。服務器只需要比較客戶端傳來的ETag跟自己服務器上該資源的ETag是否一致,就能很好地判斷資源相對客戶端而言是否被修改過了
Etag:
服務器響應請求時,告訴瀏覽器當前資源在服務器的唯一標識(生成規則由服務器決定)。
If-None-Match:
再次請求服務器時,通過此字段通知服務器客戶段緩存數據的唯一標識。
服務器收到請求后發現有頭If-None-Match 則與被請求資源的唯一標識進行比對,
不同,說明資源又被改動過,則響應整片資源內容,返回狀態碼200;
相同,說明資源無新修改,則響應HTTP 304,告知瀏覽器繼續使用所保存的cache。
注意:如果同時存在兩對字段,需要都通過才能使用緩存
總結
對于強制緩存,服務器通知瀏覽器一個緩存時間,在緩存時間內,下次請求,直接用緩存,不在時間內,執行比較緩存策略。
對于比較緩存,將緩存信息中的Etag和Last-Modified通過請求發送給服務器,由服務器校驗,返回304狀態碼時,瀏覽器直接使用緩存。
瀏覽器第一次請求:
瀏覽器再次請求時:
摘抄于:http://www.cnblogs.com/vajoy/p/5341664.html、http://www.cnblogs.com/chenqf/p/6386163.html
十 解決HTTP無狀態的問題
10.1 通過cookies保存狀態信息
cookies實際上是一個保存在客戶端上的,網站為了辨別用戶身份而儲存在用戶本地終端(Client Side)上的數據(通常經過加密),Cookie就是服務器暫存放在你的電腦里的資料(.txt格式的文本文件),通過在HTTP傳輸中的狀態好讓服務器用來辨認你的計算機。當你在瀏覽網站的時候,Web服務器會先送一小小資料放在你的計算機上,Cookie 會幫你在網站上所打的文字或是一些選擇都記錄下來。
通過Cookies,服務器就可以清楚的知道請求2和請求1來自同一個客戶端。
10.2 通過session保存狀態信息
Session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存
Session的實現方式:
1、使用Cookie來實現
服務器給每個Session分配一個唯一的JSESSIONID,并通過Cookie發送給客戶端。
當客戶端發起新的請求的時候,將在Cookie頭中攜帶這個JSESSIONID。這樣服務器能夠找到這個客戶端對應的Session。
2、使用URL回寫來實現
URL回寫是指服務器在發送給瀏覽器頁面的所有鏈接中都攜帶JSESSIONID的參數,這樣客戶端點擊任何一個鏈接都會把JSESSIONID帶會服務器。如果直接在瀏覽器輸入服務端資源的url來請求該資源,那么Session是匹配不到的。
Tomcat對Session的實現,是一開始同時使用Cookie和URL回寫機制,如果發現客戶端支持Cookie,就繼續使用Cookie,停止使用URL回寫。如果發現Cookie被禁用,就一直使用URL回寫。jsp開發處理到Session的時候,對頁面中的鏈接記得使用response.encodeURL() 。
10.3、通過表單變量保持狀態
除了Cookies之外,還可以使用表單變量來保持狀態,比如Asp.net就通過一個叫ViewState的Input=“hidden”的框來保持狀態,比如:
這個原理和Cookies大同小異,只是每次請求和響應所附帶的信息變成了表單變量。
10.4、通過QueryString保持狀態
QueryString通過將信息保存在所請求地址的末尾來向服務器傳送信息,通常和表單結合使用,一個典型的QueryString比如:www.xxx.com/xxx.aspx?var1=value&var2=value2
注意:這里說一點自己的見解,保持狀態我感覺是服務器對某個狀態進行標識,這樣子其實是很像session機制的,具體看下面
十一 cookies與session
11.1 含義
cookie機制
Cookies是服務器在本地機器上存儲的小段文本并隨每一個請求發送至同一個服務器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie規范。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies并將它們保存為一個本地文件,它會自動將同一服務器的任何請求縛上這些cookies 。
具體來說cookie機制采用的是在客戶端保持狀態的方案。它是在用戶端的會話狀態的存貯機制,他需要用戶打開客戶端的cookie支持。cookie的作用就是為了解決HTTP協議無狀態的缺陷所作的努力。
正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則在后臺自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。
cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成cookie的作用范圍。若不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存里,當然這種行為并不是規范規定的。若設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。存儲在硬盤上的cookie可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內存里的cookie,不同的瀏覽器有不同的處理方式。(故也有內存cookie和硬盤cookie之分)
而session機制采用的是一種在服務器端保持狀態的解決方案。同時我們也看到,由于采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的。而session提供了方便管理全局變量的方式
session是針對每一個用戶的,變量的值保存在服務器上,用一個sessionID來區分是哪個用戶session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置為由get來返回給服務器。
就安全性來說:當你訪問一個使用session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的session機制更安全些,因為它不會任意讀取客戶存儲的信息
session機制
session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端創建過session,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。
經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。
11.2 作用
都是可以進行保持狀態的一種機制
11.3 區別
11.3.1 存取方式的不同
cookie只能存儲ASCII字符串
session可以存儲任意類型的數據
11.3.2 隱私策略的不同
Cookie存儲在客戶端閱讀器中,對客戶端是可見的,客戶端的一些程序可能會窺探、復制以至修正Cookie中的內容。而Session存儲在服務器上,對客戶端是透明的,不存在敏感信息泄露的風險。
假如選用Cookie,比較好的方法是,敏感的信息如賬號密碼等盡量不要寫到Cookie中。最好是像Google、Baidu那樣將Cookie信息加密,提交到服務器后再進行解密,保證Cookie中的信息只要本人能讀得懂。而假如選擇Session就省事多了,反正是放在服務器上,Session里任何隱私都能夠有效的保護
11.3.3 有效期上的不同
使用過Google的人都曉得,假如登錄過Google,則Google的登錄信息長期有效。用戶不用每次訪問都重新登錄,Google會持久地記載該用戶的登錄信息。要到達這種效果,運用Cookie會是比較好的選擇。只需要設置Cookie的過期時間屬性為一個很大很大的數字。
由于Session依賴于名為JSESSIONID的Cookie,而Cookie JSESSIONID的過期時間默許為–1,只需關閉了閱讀器該Session就會失效,因而Session不能完成信息永世有效的效果。運用URL地址重寫也不能完成。而且假如設置Session的超時時間過長,服務器累計的Session就會越多,越容易招致內存溢出
11.3.4 服務器壓力不同
Session是保管在服務器端的,每個用戶都會產生一個Session。假如并發訪問的用戶十分多,會產生十分多的Session,耗費大量的內存。因而像Google、Baidu、Sina這樣并發訪問量極高的網站,是不太可能運用Session來追蹤客戶會話的。
而Cookie保管在客戶端,不占用服務器資源。假如并發閱讀的用戶十分多,Cookie是很好的選擇。關于Google、Baidu、Sina來說,Cookie或許是唯一的選擇。
11.3.5? 瀏覽器支持的不同
Cookie是需要客戶端瀏覽器支持的。假如客戶端禁用了Cookie,或者不支持Cookie,則會話跟蹤會失效。關于WAP上的應用,常規的Cookie就派不上用場了。
假如客戶端瀏覽器不支持Cookie,需要運用Session以及URL地址重寫。需要注意的是一切的用到Session程序的URL都要進行URL地址重寫,否則Session會話跟蹤還會失效。關于WAP應用來說,Session+URL地址重寫或許是它唯一的選擇。
假如客戶端支持Cookie,則Cookie既能夠設為本瀏覽器窗口以及子窗口內有效(把過期時間設為–1),也能夠設為一切閱讀器窗口內有效(把過期時間設為某個大于0的整數)。但Session只能在本閱讀器窗口以及其子窗口內有效。假如兩個瀏覽器窗口互不相干,它們將運用兩個不同的Session。(IE8下不同窗口Session相干)
11.3.6 跨域支持上的不同
Cookie支持跨域名訪問,例如將domain屬性設置為“.biaodianfu.com”,則以“.biaodianfu.com”為后綴的一切域名均能夠訪問該Cookie??缬蛎鸆ookie如今被普遍用在網絡中,例如Google、Baidu、Sina等。而Session則不會支持跨域名訪問。Session僅在他所在的域名內有效。
僅運用Cookie或者僅運用Session可能完成不了理想的效果。這時應該嘗試一下同時運用Cookie與Session。Cookie與Session的搭配運用在實踐項目中會完成很多意想不到的效果
11.4 聯系
客戶第一次發送請求給服務器,此時服務器產生一個唯一的sessionID,并返回給客戶端(通過cookie),保存于客戶端的內存中,并與一個瀏覽器窗口對應著,由于HTTP協議的特性,這一次連接就斷開了。
以后此客戶端再發送請求給服務器的時候,就會在請求request中攜帶cookie,由于cookie中有sessionID,所以服務器就知道這是剛才那個客戶端。
也就是說cookie可以存儲sessionid的一種標識。
摘抄來自于:http://blog.csdn.net/weixin_37196194/article/details/55806366
十二 http2的新特性
? ? ? ? 2015年發布的http2
12.1 二進制協議
HTTP/1.1 版的頭信息肯定是文本(ASCII編碼),數據體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協議,頭信息和數據體都是二進制,并且統稱為"幀"(frame):頭信息幀和數據幀。
二進制協議的一個好處是,可以定義額外的幀。HTTP/2 定義了近十種幀,為將來的高級應用打好了基礎。如果使用文本實現這種功能,解析數據將會變得非常麻煩,二進制解析則方便得多
12.2 多工
HTTP/2 復用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"。(隊頭阻塞意思是客戶端或者服務器發送消息的時候,如果某條數據太大,那么需要的時間就要很長,后面等待發送的就會有很多,造成堵塞)
舉例來說,在一個TCP連接里面,服務器同時收到了A請求和B請求,于是先回應A請求,結果發現處理過程非常耗時,于是就發送A請求已經處理好的部分, 接著回應B請求,完成后,再發送A請求剩下的部分。
這樣雙向的、實時的通信,就叫做多工(Multiplexing)
12.3 數據包
由于多工的特性存在,http2的數據包是不按順序發送的,同一個連接里面連續的數據包,可能屬于不同的回應。因此,必須要對數據包做標記,指出它屬于哪個回應。
HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流(stream)。每個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流ID,用來區分它屬于哪個數據流。另外還規定,客戶端發出的數據流,ID一律為奇數,服務器發出的,ID為偶數。
數據流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。
客戶端還可以指定數據流的優先級。優先級越高,服務器就會越早回應。
12.4 頭信息壓縮
HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重復的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。
HTTP/2 對這一點做了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發送同樣字段了,只發送索引號,這樣就提高速度了。
12.5 服務器推送
HTTP/2 允許服務器未經請求,主動向客戶端發送資源,這叫做服務器推送(server push)。
常見場景是客戶端請求一個網頁,這個網頁里面包含很多靜態資源。正常情況下,客戶端必須收到網頁后,解析HTML源碼,發現有靜態資源,再發出靜態資源請求。其實,服務器可以預期到客戶端請求網頁后,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了。
這里可以去搜搜看阮一峰的網絡日志中關于http協議這一篇,寫的簡短又有內涵