深入web請求

如何發起一個web請求

其實發起一個http請求和建立一個socket連接區別不大,只不過outputStream.write裏邊二進制字節數據格式要符合http的標準,瀏覽器在建立socket連接之前,根據在地址欄輸入的域名DNS解析出ip地址,再根據這個ip地址和默認的80端口與遠程服務器建立socket連接,然後瀏覽器根據這個URL組裝成一個get類型的HTTP請求頭,通過outputStream.write發送到目標服務器,服務器等待InputStream.read返回數據最後斷開連接。

總結就是。http請求就是建立一個短暫的socket連接的過程。
java中使用httpclient類就可以模擬請求過程,如果對請求非常熟悉,甚至可以自己寫一個httpclient工具包,甚至是瀏覽器。

HTTP解析

B/S架構的核心是HTTP,掌握HTTP協議對從事互聯網工作的程序員非常重要,有一句話說的是“你能對這個工作做得多好,取決於你對它瞭解的多深”。

要理解http,最重要的是熟悉HTTP中的HTTP header,它控制着成千上萬的用戶的數據的傳輸,最關鍵的是它控制着用戶瀏覽器的渲染行爲和服務器的執行邏輯,例如,當服務器沒有用戶請求的數據時就會返回一個404的狀態碼。

常見的請求頭

  • Accept-Charset 用於指定客戶端接受的字符集
  • Accept-Encoding 用於指定可接受的內容編碼,如:gzip,deflate。(我之前做網站時,進行百度的評分要求一定要開啓gzip壓縮)
  • Accept-Language 用於指定自然語言 如:zh-cn(中文)
  • Host 指定被請求資源的Internet主機和端口號
  • User-Agent 客戶端將它的操作系統 、瀏覽器和其他屬性告訴服務器(通過這個參數可以判斷是要訪問移動端網站還是pc端)
  • Connection 當前連接是否保持 如:keep-alive

常見的HTTP響應頭

  • Server 使用的服務器名稱,如:Server:Apache/1.3.6(Unix)
  • Content-type 指明實體正文的媒體類型,如text/html;charset=GBK,移動端一般是Json或者xml
  • Content-Encoding 與Accpet-Encoding對應,壓縮編碼類型
  • Content-Language 自然語言,與Accept-Language對應
  • Content-Length 指明實體正文的長度,用以字節方式存儲的十進制來表示
  • Keep-Alive 保持連接的時間,如keep-alive:timout=5 max=120

常見的HTTP狀態碼
- 200 請求成功
- 302 臨時跳轉,地址通過location指定
- 400 客戶請求有語法錯誤,不能識別。
- 403 服務器收到請求,但拒絕提供服務
- 404 請求的資源不存在
- 500 服務器發生不可預期的錯誤

要查看http信息可以通過瀏覽器的開發者模式,firefox和chrome一般是首選。

比如我們百度一下。
請求頭

Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://i.g-fox.cn/rd20.html?engine=baidu_web&q=java+web
Cookie: BAIDUID=C89E73E5EB7AC49C48889FB255CA9773:FG=1; BAIDUPSID=C89E73E5EB7AC49C48889FB255CA9773; BD_UPN=13314352
Connection: keep-alive

響應頭

BDPAGETYPE: 3
BDQID: 0xd3d806820001e99a
BDUSERID: 0
CKPACKNUM: 2
CKRNDSTR: 20001e99a
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 71179
Content-Type: text/html;charset=utf-8
Date: Sun, 01 Mar 2015 06:56:10 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM ", CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'
Proxy-Connection: keep-alive
Server: BWS/1.1
Set-Cookie: BDRCVFR[kpkBv0s1F-3]=srT4swvGNE6uzdhUL68mv3; path=/; domain=.baidu.com
BD_CK_SAM=1;path=/
BDSVRTM=8; path=/
H_PS_PSSID=1430_10632; path=/; domain=.baidu.com
Vary: Accept-Encoding
X-Powered-By: HPHP

瀏覽器緩存機制

有時候瀏覽器在瀏覽頁面時發現頁面有異常,我們就可以使用Ctrl+F5來刷新一下,重新請求一次這個頁面。而不會使用緩存的數據。不過請求到的也有可能是緩存的數據,比如大部份高流量的網站爲了節約性能都設置一個緩存服務器,如Varnish代理。

比如我們刷新一下剛纔的請求

Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://i.g-fox.cn/rd20.html?engine=baidu_web&q=java+web
Cookie: BAIDUID=C89E73E5EB7AC49C48889FB255CA9773:FG=1; BAIDUPSID=C89E73E5EB7AC49C48889FB255CA9773; BD_UPN=13314352; BDRCVFR[kpkBv0s1F-3]=srT4swvGNE6uzdhUL68mv3; BD_CK_SAM=1; H_PS_PSSID=1430_10632; H_PS_645EC=2927JYDA6%2BKfUJaJOgPVoYsN6IOCKN31hMlR79MbEpYwXYkL6aNX%2FeHB71Se2DvRlfH%2B
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

看比原來多了兩個參數
Pragma: no-cache
Cache-Control: no-cache

Cache-Control: no-cache/proma的作用

這個http head字段用於指定所有緩存機制在整個請求/響應中必須服從的指令,如果知道該頁面是否爲緩存 ,不但可以控制瀏覽器,還可以控制和http相關的緩存或代理服務器。
http 可選字段
- Public :所有內容都將被緩存,在響應頭的設置
- Private :內容只緩存到私有緩存中,在響應頭中設置
- no-cache :所有內容都不會被緩存,在請求和響應頭的設置
- no-store:所有內容都不會被緩存到緩存或Internet臨時文件中,在響應頭的設置
- must-revalidation/proxy-revalidation 如果緩存的內容失效,請求必須發送到服務器/代理以進行重新驗證。在請求頭中設置
- max-age=xxx:緩存的內容將在xxx秒後失效 。這個選項只在http1.1中可用,和last-Modified一起使用時優先級較高,在響應頭中設置

cache-control請求字段被各個瀏覽器支持得較好。它和Expires同時出現時,Cache-control會覆蓋其他字段 。

Expires
格式爲:Sat,25 Feb 2012 12:00:00 GMT 超過這個時間後。緩存的內容將失效,也就是瀏覽器在發出請求之前檢查這個頁面的這個字段,看該頁面是否已經過期了,過期了就重新向服務器發起請求。

Last-Modified/Etag
這個字段被用於表示一個服務器上的資源的最後修改時間,資源可以是靜態(靜態內容自動加上Last-Modified字段)或者動態的內容(如Servlet提供了一個getLastModified方法用於檢查某個動態內容是否已經更新)。

一般服務端在響應頭中返回一個Last-Modified字段:Sat,25 Feb 2012 12:00:00 GMT ,當瀏覽器再次請求時在請求頭中增加一個If-Modified-Since:Sat,25 Feb 2012 12:00:00 GMT 字段,詢問當前緩存的頁面是否是最新的。如果是最新的就返回304狀態碼。服務器就不會在傳輸新的數據 。
與Last-Modified字段 有類似功能的還有一個Etag字段,這個字段 是讓服務器給每個頁面分配 一個唯一的編號,然後通過這個編號來區分當前這個頁面是否是最新的。

CDN工作機制

CDN是內容分佈網絡(Content delivery Network)其目的是通過現有的Internet中增加一層新的網絡架構,將網站的內容發佈到最接近用戶的網絡“邊緣”,使用用戶可以就近取得所需的內容。
CDN=鏡像+緩存+整體負載均衡。

比如CSS JS 圖片和靜態頁面等數據 ,都是從主站請求到動態內容後,再從CDN上下載這些靜態數據 ,從而加速內容下載速度。如淘寶有90%的數據都是由CDN來提供 。

我們知道DNS解析是最後會通過離你最近的DNS服務器解析給你ip地址。CDN的工作機制就是在DNS的解析過程中間,解析到過一個屬於公司的DNS服務器。然後再解析給離你最近的公司資源服務器來下載資源。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章