什么是HTTP Headers? 它包含了哪些內容? 利用requests.get()函數對豆瓣讀書進行請求, 返回的r.headers如下所示:
>>> import requests >>> r = requests.get('https://book.douban.com/') >>> r.headers {'X-Powered-By-ADS': 'chn-shads-4-12', 'X-Xss-Protection': '1; mode=block', 'X-DAE-App': 'book', 'X-Content-Type-Options': 'nosniff', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', 'Set-Cookie': 'bid=ZT-mRsxMMX0; Expires=Mon, 23-Oct-17 03:11:40 GMT; Domain=.douban.com; Path=/, __ads_session=2Yy49z4EzghqOiuo9gA=; domain=.douban.com; path=/', 'Expires': 'Sun, 1 Jan 2006 01:00:00 GMT', 'Vary': 'Accept-Encoding', 'X-DAE-Node': 'nain3', 'Server': 'ADSSERVER/44619', 'X-Douban-Mobileapp': '0', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'must-revalidate, no-cache, private', 'Date': 'Sun, 23 Oct 2016 03:11:40 GMT', 'Strict-Transport-Security': 'max-age=15552000;', 'X-DOUBAN-NEWBID': 'ZT-mRsxMMX0', 'Content-Type': 'text/html; charset=utf-8'}
'Content-Type': 'text/html; charset=utf-8'
這個是文檔的mime-type, 瀏覽器根據此參數來決定如何對文檔進行解析. 例如一個html頁面返回值就是:
'text/html; charset=utf-8';
/前的'text'表示文檔類型, /后面的'html'表示文檔的子類型;
如果是圖片,則返回: 'image/jpeg', 表示目標是一個圖像(image), 具體是一個jpeg圖像.
>>> p = requests.get('http://pic33.nipic.com/20130916/3420027_192919547000_2.jpg') >>> p.headers['content-type'] 'image/jpeg'
如果是pdf文檔, 則返回'application/pdf'
>>> import requests >>> s = requests.get('http://www.em-consulte.com/showarticlefile/738819/main.pdf') >>> s.headers['Content-Type'] 'application/pdf'
mime-type類型不止這三個, 還有其他的mime-type類型在這里可以看到.
'Cache-Control': 'must-revalidate, no-cache, private'
緩存控制字段用於指定所有緩存機制在整個請求/響應中必須服從的指令. 常見的取值有: private(默認), no-cache, max-age, must-revalidate
Cache指令 | 說明 |
public | 所有的內容都將被緩存(客戶端和代理服務器都可緩存) |
private | 內容只緩存到私有緩存中(客戶端可緩存,代理服務器不可) |
no-cache | 必須先與服務器確認返回的相應是否被更改,然后才能使用該響應來滿足對同一個網址的請求 |
must-revalidate | 若緩存內容失效,請求必須發送到服務器/代理以進行重新驗證 |
max-age=*** | 緩存內容將在***s之后失效 |
緩存技術可以減輕服務器負載, 降低網絡阻塞, 其基本思想是利用了客戶訪問的時間局部性(temporary location)原理, 將客戶訪問的內容在Cache里面放一個副本, 這樣, 如果該內容再次被訪問, 則不用再次發送請求, 而且直接將次網頁從Cache里面拿出. 這個機制很好, 但是也可能造成問題: 1) 用戶可能再次請求獲取到的內容是過期的內容; 2) 如果緩存失效, 客戶的訪問延遲反而會比直接請求要增加;
'Expires': 'Sun, 1 Jan 2006 01:00:00 GMT'
Expires(期限)提供一個日期和時間, 響應在該日期和時間后被認為失效. 在過期時間前可以從緩存中取得數據, 而不需要再次請求.
它有一個缺點是它返回的是服務器端的時間, 如果客戶端時間和服務器端時間不相同或者差別很大, 那么誤差比較大. 有了Cache-control的max-age, 這個expires功能被替代.
Cache-control的優先級高於Expires, 都是用來指明當前資源的有效期. 但是Cache-control的設置更加細致.
第一次請求的過程:
第二次請求的過程:
'Content-Encoding': 'gzip'
1. 客戶端向服務器發送HTTP request, request里面有Accept-Encoding: gzip, deflate (告訴服務器瀏覽器支持gzip壓縮)
2. 服務器收到請求后, 生成原始的response, 其中有原始的Content-Type, Content-Length
3. 服務器通過gzip對response進行編碼, 編碼后的headers里面有Content-Type, Content-Length, 而且還有Content-Encoding: gzip, 然后把此response發送給客戶端
4. 客戶端收到response后, 根據Content-Encoding: gzip對response進行解碼, 獲取未壓縮的response.
'Set-Cookie': 'bid=ZT-mRsxMMX0; Expires=Mon, 23-Oct-17 03:11:40 GMT; Domain=.douban.com; Path=/, __ads_session=2Yy49z4EzghqOiuo9gA=; domain=.douban.com; path=/'
cookie是web服務器向客戶端發送的一段ASCII碼文本, 一旦收到了cookie, 瀏覽器會把cookie的信息片段以"名/值"對(name-value pairs)的形式存儲在本地. 這以后, 每當向同一個web服務器請求一個新文檔時, web服務器變回發送之前存儲在本地的cookie. 創建cookie最初的目的是想讓web 服務器能夠通過多個HTTP請求追蹤客戶.
參考:
[1] 瀏覽器 HTTP 協議緩存機制詳解: https://my.oschina.net/leejun2005/blog/369148
[2] HTTP請求中的緩存(cache)機制: http://blog.chinaunix.net/uid-11639156-id-3214858.html
[3] http壓縮 Content-Encoding: gzip: http://liuviphui.blog.163.com/blog/static/20227308420141843933379/
[4] 完整的Set-Cookie 頭: http://blog.sina.com.cn/s/blog_70c4d9410100z3il.html