整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          三句話測試你是否懂git

          事和組長的一番對話引起了筆者對 git 的思考

          先介紹一下我司小工坊式的 git 提交流程,本地打包,刪除 dist 文件,重建 dist 文件,git add .git commit -m 'XX'git push origin 分支名

          和傳統(tǒng)公司的 git 提交不同,我司打包是本地打包,而且是把 dist 文件直接上傳到倉庫

          事故現(xiàn)象

          同事把代碼推上去后,瀏覽器訪問的還是原來的 js 和 css。

          同事說:組長,需要你把 dist 刪掉,重新再從倉庫里拉一下最新的

          組長:git 提交后不就把原來的 dist 替換了嗎,你讓我刪 dist 有什么意義

          扯皮了一會兒,組長還是刪了然后重新拉,沒想到好了

          組長說:你的 dist 現(xiàn)在是最新的,所以現(xiàn)在就好了

          同事具體說了什么筆者忘記了,大致上在辯護(hù) git 提交不會把原來的 dist 文件刪除問題,不過他沒說服組長,組長也沒說服他,反正已經(jīng)安全上線而不了了之。

          我正好在旁邊聽到了,要是兩年前我也許會一直提出問題參與辯論,申援同事。但筆者沒動,不是怕 PUA,而是表達(dá)能力太差,即使是對的,也說不好。其根本原因是筆者對這塊知識了解的不深刻,所以不敢說大話

          理論知識

          按照理論知識,你 push 整個(gè) dist 文件,即使遠(yuǎn)程倉庫中有 dist,也不會把整個(gè) dist 文件夾替換,只會替換其中相同的數(shù)據(jù),而因?yàn)榇蛄?hash 值,所以 css 和 js 都是不同的,所以一直這樣做,dist 中的文件會越來越多,而因?yàn)?index.html 文件只有一個(gè),所以不會出現(xiàn)替換了還引用之前文件的問題,如果出現(xiàn),清除下瀏覽器的緩存就能解決

          實(shí)戰(zhàn)檢驗(yàn)

          因?yàn)樯a(chǎn)環(huán)境和測試環(huán)境發(fā)布代碼流程不同,所以先要把環(huán)境配置成一致先

          需要做的事情很簡單,把 nginx 中指向倉庫地址,到時(shí)候從遠(yuǎn)端拉下代碼即可

          先修改 nginx 中的配置

          server {
              listen 7000;
              # root /usr/share/nginx/html/dist
              root /home/jingqb-web/dist
              ...
          }

          再檢查一下 nginx 配置是否 ok

          nginx -t

          接著重啟 nginx

          nginx -s reload

          接著把代碼提交到遠(yuǎn)端倉庫,再上服務(wù)器進(jìn)入 /home/jingqb-web 目錄下,git pull origin XX ,進(jìn)入 dist 文件,查看打包后的 js

          原js的hash值

          我們修改在項(xiàng)目中打印一些日志,表示文件改動,這樣 build 之后會打出不同 hash 的 js

          git push origin XX

          再次登錄服務(wù)器,進(jìn)入 /home/jingqb-web 目錄,再拉代碼git pull origin xx

          再次提交后的代碼

          發(fā)現(xiàn),umi.b0f5511b.js 被刪掉了,新生成的 umi.f8280c0e.js 在其中,dist 中是干凈的源文件,這是為什么呢?

          你 build 之后,是先刪掉 dist 文件,生成的是一個(gè)干凈的 dist,然后我的操作是:

          • git add .
          • git commit -m 'XX'
          • git push origin 'XX 分支'

          我的操作中沒有 pull 代碼,而是直接 push 代碼,這就意味著 dist 就是我本地的 dist,而非合并之后的

          想想這種做法的缺點(diǎn)是多人開發(fā)時(shí),pull 別人的代碼后,merge 之后還要重新 build,才能再次提交

          好險(xiǎn),還好沒有逞英雄

          謹(jǐn)言慎行是一輩子的學(xué)問

          三句話測試你是否懂 git

          這觸發(fā)了筆者對 git 的新認(rèn)知,結(jié)合平時(shí)經(jīng)驗(yàn),筆者覺得三個(gè)問題能測試別人對 git 的理解程度

          1. 你和同事基于同一 commit 開發(fā),后續(xù)合并時(shí),如何按照時(shí)間順序顯示提交記錄 git rebase master XX(分支)獲得更優(yōu)雅的提交樹
          2. 代碼如何回滾 git reset --hard XX把當(dāng)前代碼指向另一個(gè)commit上
          3. 你開發(fā)代碼,提交了好幾個(gè) commit,后續(xù)使用 git reset --hard xxxxx 把代碼指針指回原始 commit ,并在這個(gè) commit 上開發(fā)了一個(gè)功能,并提交了一個(gè) commit,怎么找回之前提交的那好幾個(gè) commit 首先使用 git reflog ,它能展示你之前所有的 git 操作 比較 git log,它不僅包括了 git log 上的操作,而且它記錄了被刪除的 commit 記錄和 reset 操作 git reset --hard XX 將 git 指針指向回到原始代碼前的那個(gè) commit git cherry-pick XX 合并二次開發(fā)時(shí)的 commitcherry-pick 意為取出,將二次開發(fā)時(shí)的 commit 取出放入主分支上

          面幾篇文章我們講到了跨站腳本(XSS)漏洞的幾種類型和驗(yàn)證方法以及防御措施,有興趣的朋友可以到我的主頁翻看文章《十大常見web漏洞——跨站腳本漏洞》和《實(shí)操web漏洞驗(yàn)證——跨站腳本漏洞》,今天我們繼續(xù)由易到難實(shí)戰(zhàn)演示一下跨站腳本漏洞的形成,以便更好地了解漏洞的產(chǎn)生原理,進(jìn)一步做好防御。

          上一篇文章我們已經(jīng)闖過了5關(guān),今天我們繼續(xù)。

          html事件中的xss

          html事件是在滿足一定條件的用戶行為發(fā)生時(shí),所觸發(fā)的的事件,例如當(dāng)單擊鼠標(biāo)時(shí)的“onclick”以及當(dāng)瀏覽器加載圖像時(shí)的“onload”,我們可以將這些特定的html事件發(fā)生時(shí),將JavaScript語句作為屬性傳遞給特定的標(biāo)簽,從而構(gòu)成一個(gè)或多個(gè)JavaScript命令或函數(shù)。

          下圖我們從網(wǎng)上搜索了一些html事件屬性,有興趣的可以自己搜索學(xué)習(xí)。

          html事件屬性

          在這一關(guān)中,我們可以構(gòu)造語句:

          111" onmouseover="alert(document.domain);"

          前邊的“111"”是為了閉合標(biāo)簽,后邊的“onmouseover”屬性表示當(dāng)鼠標(biāo)移動到輸入框時(shí)執(zhí)行后邊的語句,點(diǎn)擊“search”按鈕,將鼠標(biāo)移動到輸入框時(shí),頁面在彈出內(nèi)容為當(dāng)前頁面域名的彈窗后,提示“恭喜!”,就可以順利進(jìn)入下一關(guān)了,如下圖所示:

          恭喜通關(guān)

          空格分隔屬性中的xss

          這一關(guān)我們先來探測一下注入點(diǎn)的情況,我們和之前一樣先閉合標(biāo)簽,輸入“123456"”來閉合標(biāo)簽,找到對應(yīng)的代碼,發(fā)現(xiàn)我們輸入的內(nèi)容被另一對引號括住了,如下圖所示:

          頁面代碼

          這表明我們輸入的內(nèi)容直接被實(shí)體化了,那我們不使用引號閉合,直接輸入“123456 onmouseover=“alert(document.domain)””,發(fā)現(xiàn)只要是等號后邊的參數(shù)都被引號括了起來,如下圖所示:

          頁面代碼

          因此我們都不加引號,構(gòu)造:

          123456 onmouseover=alert(document.domain)

          注意中間有個(gè)空格,點(diǎn)擊“search”按鈕時(shí),頁面在彈出內(nèi)容為當(dāng)前頁面域名的彈窗后,提示“恭喜!”,就可以順利進(jìn)入下一關(guān)了,如下圖所示:

          恭喜通關(guān)

          JavaScript偽協(xié)議觸發(fā)XSS

          有時(shí)候我們需要將JavaScript代碼添加到客戶端中,這時(shí)就需要JavaScript偽協(xié)議來幫助,它的格式為JavaScript:url,例如:JavaScript:alert("hello word!"),就是一個(gè)簡單的通過JavaScript偽協(xié)議來執(zhí)行alert("hello word!")語句,它表示在頁面顯示“hello word!”。

          因此我們可以構(gòu)造語句

          JavaScript:alert(document.domain);

          點(diǎn)擊“Make a Link”按鈕時(shí),可見輸入框下邊出現(xiàn)一個(gè)URL超鏈接,我們點(diǎn)擊這個(gè)鏈接,如下圖所示:

          URL超鏈接

          頁面在彈出內(nèi)容為當(dāng)前頁面域名的彈窗后,提示“恭喜!”,就可以順利進(jìn)入下一關(guān)了,如下圖所示:

          恭喜通關(guān)

          UTF-7中的xss

          這個(gè)比較簡單,因?yàn)閁TF-7絕大多數(shù)瀏覽器都已經(jīng)不用了,我們很少會遇到,因此我們直接構(gòu)造語句:

          onclick=alert(document.domain);

          我們按F12鍵,根據(jù)下圖提示找到第三步位置,將以上語句寫入到對應(yīng)位置,再點(diǎn)擊第二步的位置,如下圖所示:

          修改頁面代碼

          頁面在彈出內(nèi)容為當(dāng)前頁面域名的彈窗后,提示“恭喜!”,就可以順利進(jìn)入下一關(guān)了,如下圖所示:

          恭喜通關(guān)

          繞過過濾domain為空的xss

          首先我們還是老辦法構(gòu)造閉合語句,如下所示:

          "><script>alert(document.domain);</script>

          點(diǎn)擊“search”,按F12,找到如下圖紅框中的位置,發(fā)現(xiàn)我們上邊構(gòu)造的語句中“domain”被刪除了,如下圖所示:

          頁面代碼

          既然被刪除了,這時(shí)我們可以通過雙寫來繞過domain被刪除這種情況,我們可以構(gòu)造:

          "><script>alert(document.dodomainmain);</script>

          注意我們在單詞domain中間又加了一個(gè)單詞domain,這時(shí)系統(tǒng)在刪除一個(gè)單詞domain后,還會留下一個(gè)domain,這樣我們就成功執(zhí)行了語句了。

          點(diǎn)擊“search”按鈕時(shí),頁面在彈出內(nèi)容為當(dāng)前頁面域名的彈窗后,提示“恭喜!”,就可以順利進(jìn)入下一關(guān)了,如下圖所示:

          恭喜通關(guān)

          當(dāng)然我們也可以通過編碼的方法來繞過,我們可以構(gòu)造:

          "><script>eval(atob('YWxlcnQoZG9jdW1lbnQuZG9kb21haW5tYWluKTs='));</script>

          其中“eval”是用來執(zhí)行字符串,其后邊的內(nèi)容會當(dāng)成JavaScript語句執(zhí)行,“atob”表示將加密的base64密文,轉(zhuǎn)換成原文,而里邊的一串亂碼就是通過base64加密過的的“alert(document.domain)”語句,關(guān)于加密,有興趣的可以閱讀我的文章《Web滲透測試——密碼學(xué)基礎(chǔ)》,其實(shí)和上邊的語句一樣,這樣就可以避免domain被刪除了。

          以上就是跨站腳本(XSS)漏洞實(shí)戰(zhàn)演示——由易到難第二部分的全部內(nèi)容,希望對你了解XSS漏洞有所幫助,歡迎關(guān)注@科技興了解更多科技尤其是網(wǎng)絡(luò)安全方面的資訊和知識。

          正式學(xué)習(xí)網(wǎng)絡(luò)爬蟲之前,我們需要詳細(xì)了解 HTTP 的基本原理,了解在瀏覽器中敲入 URL 到獲取網(wǎng)頁內(nèi)容之間發(fā)生了什么。了解這些內(nèi)容,有助于我們進(jìn)一步了解爬蟲的基本原理。

          1.1 HTTP 基本原理

          在本節(jié)中,我們會詳細(xì)了解 HTTP 的基本原理,了解在瀏覽器中敲入 URL 到獲取網(wǎng)頁內(nèi)容之間發(fā)生了什么。了解這些內(nèi)容,有助于我們進(jìn)一步了解爬蟲的基本原理。

          1. URI 和 URL

          這里我們先了解一下 URI 和 URL。URI 的全稱為 Uniform Resource Identifier,即統(tǒng)一資源標(biāo)志符;而 URL 的全稱為 Universal Resource Locator,即統(tǒng)一資源定位符。舉例來說,github.com/favicon.ico 是一個(gè) URL,也是一個(gè) URI。即有這樣一個(gè)圖標(biāo)資源,我們用 URL/URI 來唯一指定了它的訪問方式,這其中包括了訪問協(xié)議 https、訪問路徑(即根目錄)和資源名稱 favicon.ico。通過這樣一個(gè)鏈接,我們便可以從互聯(lián)網(wǎng)上找到這個(gè)資源,這就是 URL/URI。

          URL 是 URI 的子集,也就是說每個(gè) URL 都是 URI,但不是每個(gè) URI 都是 URL。那么,怎樣的 URI 不是 URL 呢?URI 還包括一個(gè)子類,叫作 URN,它的全稱為 Universal Resource Name,即統(tǒng)一資源名稱。URN 只命名資源而不指定如何定位資源,比如 urn:isbn:0451450523 指定了一本書的 ISBN,可以唯一標(biāo)識這本書,但是沒有指定到哪里定位這本書,這就是 URN。URL、URN 和 URI 的關(guān)系可以用圖 1-1 表示。

          但是在目前的互聯(lián)網(wǎng),URN 使用得非常少,幾乎所有的 URI 都是 URL,所以對于一般的網(wǎng)頁鏈接,我們既可以稱之為 URL,也可以稱之為 URI,我個(gè)人習(xí)慣稱之為 URL。

          但 URL 也不是隨便寫的,它也是需要遵循一定的格式規(guī)范的,基本的組成格式如下:

          scheme://[username:password@]hostname[:port][/path][;parameters][?query][#fragment]
          復(fù)制代碼

          其中這些括號包括的內(nèi)容代表非必要部分,比如 www.baidu.com 這個(gè) URL,這里就只包含了 scheme 和 host 兩部分,其他的 port、path、parameters、query、fragment 都沒有。

          這里我們分別介紹下幾部分代表的含義和作用:

          • scheme:協(xié)議。比如常用的協(xié)議有 http、https、ftp 等等,另外 scheme 也被常稱作 protocol,都代表協(xié)議的意思。
          • username、password:用戶名和密碼。在某些情況下 URL 需要提供用戶名和密碼才能訪問,這時(shí)候可以把用戶名密碼放在 host 前面。比如 ssr3.scrape.center 這個(gè) URL 需要用戶名密碼才能訪問,那么可以直接寫為 admin:admin@ssr3.scrape.center 則可以直接訪問。
          • hostname:主機(jī)地址。可以是域名或 IP 地址,比如 www.baidu.com 這個(gè) URL 中的 hostname 就是 www.baidu.com,這就是百度的二級域名。比如 https://8.8.8.8 這個(gè) URL 中 hostname 就是 8.8.8.8,它是一個(gè) IP 地址。
          • port:端口。這是服務(wù)器設(shè)定的服務(wù)端口,比如 https://8.8.8.8:12345 這個(gè) URL 中的端口就是 12345。但是有些 URL 中沒有端口信息,這是使用了默認(rèn)的端口,http 協(xié)議的默認(rèn)端口是 80,https 協(xié)議的默認(rèn)端口是 443。所以 www.baidu.com 其實(shí)相當(dāng)于 www.baidu.com:443,而 www.baidu.com 其實(shí)相當(dāng)于 www.baidu.com:80。
          • path:路徑。指的是網(wǎng)絡(luò)資源在服務(wù)器中的指定地址,比如 github.com/favicon.ico 這里 path 就是 favicon.ico,指的就是訪問 GitHub 上的根目錄下的 favicon.ico 這個(gè)資源。
          • parameters:參數(shù)。用來制定訪問某個(gè)資源的時(shí)候的附加信息,比如 https://8.8.8.8:12345/hello;user 這里的 user 就是 parameters。但是 parameters 現(xiàn)在用得很少,所以目前很多人會把該參數(shù)后面的 query 部分稱為參數(shù),甚至把 parameters 和 query 混用。嚴(yán)格意義上來說,parameters 是分號 ; 后面的內(nèi)容。
          • query:查詢。用來查詢某類資源,如果有多個(gè)查詢,則用 & 隔開。query 其實(shí)非常常見,比如 www.baidu.com/s?wd=nba&ie… query 部分就是 wd=nba&ie=utf-8,這里指定了 wd 是 nba,ie 是 utf-8。由于 query 比剛才所說的 parameters 使用頻率高太多,所以平時(shí)我們見到的參數(shù)、GET 請求參數(shù)、parameters、params 等稱呼多數(shù)情況指代的也是 query。嚴(yán)格意義上來說,其實(shí)應(yīng)該用 query 來表示。
          • fragment:片段。它是對資源描述的部分補(bǔ)充,可以理解為資源內(nèi)部的書簽。目前它有兩個(gè)主要應(yīng)用,一個(gè)是用作單頁面路由,比如 現(xiàn)代前端框架 Vue、React 都可以借助它來做路由管理;另外一個(gè)應(yīng)用是用作 HTML 錨點(diǎn),用它可以控制一個(gè)頁面打開時(shí)自動下滑滾動到某個(gè)特定的位置。

          以上我們就簡單了解了 URL 的基本概念和構(gòu)成,后文我們會結(jié)合多個(gè)實(shí)戰(zhàn)案例練習(xí)來幫助加深其理解。

          2. HTTP 和 HTTPS

          剛才我們了解了 URL 的基本構(gòu)成,其支持的協(xié)議有很多,比如 http、https、ftp、sftp、smb 等等。

          在爬蟲中,我們抓取的頁面通常基于 http 或 https 協(xié)議,這里首先我們先來了解一下這兩個(gè)協(xié)議的含義。

          HTTP 的全稱是 Hyper Text Transfer Protocol,中文名叫作超文本傳輸協(xié)議。HTTP 協(xié)議是用于從網(wǎng)絡(luò)傳輸超文本數(shù)據(jù)到本地瀏覽器的傳送協(xié)議,它能保證高效而準(zhǔn)確地傳送超文本文檔。HTTP 由萬維網(wǎng)協(xié)會(World Wide Web Consortium)和 Internet 工作小組 IETF(Internet Engineering Task Force)共同合作制定的規(guī)范,目前廣泛使用的是 HTTP 1.1 版本,當(dāng)然 HTTP 2.0 現(xiàn)在不少網(wǎng)站也增加了支持。

          其發(fā)展歷史見下表:

          版本

          產(chǎn)生時(shí)間

          主要特點(diǎn)

          發(fā)展現(xiàn)狀

          HTTP/0.9

          1991 年

          不涉及數(shù)據(jù)包傳輸,規(guī)定客戶端和服務(wù)器之間通信格式,只能 GET 請求

          沒有作為正式的標(biāo)準(zhǔn)

          HTTP/1.0

          1996 年

          傳輸內(nèi)容格式不限制,增加 PUT、PATCH、HEAD、 OPTIONS、DELETE 命令

          正式作為標(biāo)準(zhǔn)

          HTTP/1.1

          1997 年

          持久連接(長連接)、節(jié)約帶寬、HOST 域、管道機(jī)制、分塊傳輸編碼

          正式作為標(biāo)準(zhǔn)并廣泛使用

          HTTP/2.0

          2015 年

          多路復(fù)用、服務(wù)器推送、頭信息壓縮、二進(jìn)制協(xié)議等

          逐漸覆蓋市場

          HTTPS 的全稱是 Hyper Text Transfer Protocol over Secure Socket Layer,是以安全為目標(biāo)的 HTTP 通道,簡單講是 HTTP 的安全版,即在 HTTP 下加入 SSL 層,簡稱為 HTTPS。

          HTTPS 的安全基礎(chǔ)是 SSL,因此通過它傳輸?shù)膬?nèi)容都是經(jīng)過 SSL 加密的,它的主要作用分為以下兩種。

          • 建立一個(gè)信息安全通道,保證數(shù)據(jù)傳輸?shù)陌踩浴?/li>
          • 確認(rèn)網(wǎng)站的真實(shí)性。凡是使用了 https 的網(wǎng)站,都可以通過點(diǎn)擊瀏覽器地址欄的鎖頭標(biāo)志來查看網(wǎng)站認(rèn)證之后的真實(shí)信息,也可以通過 CA 機(jī)構(gòu)頒發(fā)的安全簽章來查詢。

          現(xiàn)在越來越多的網(wǎng)站和 App 都已經(jīng)向 HTTPS 方向發(fā)展,舉例如下。

          • 蘋果公司強(qiáng)制所有 iOS App 在 2017 年 1 月 1 日前全部改為使用 HTTPS 加密,否則 App 就無法在應(yīng)用商店上架。
          • 谷歌從 2017 年 1 月推出的 Chrome 56 開始,對未進(jìn)行 HTTPS 加密的網(wǎng)址亮出風(fēng)險(xiǎn)提示,即在地址欄的顯著位置提醒用戶 “此網(wǎng)頁不安全”。
          • 騰訊微信小程序的官方需求文檔要求后臺使用 HTTPS 請求進(jìn)行網(wǎng)絡(luò)通信,不滿足條件的域名和協(xié)議無法請求。

          因此,HTTPS 已經(jīng)是大勢所趨。

          注:HTTP 和 HTTPS 協(xié)議都屬于計(jì)算機(jī)網(wǎng)絡(luò)中的應(yīng)用層協(xié)議,其下層是基于 TCP 協(xié)議實(shí)現(xiàn)的,TCP 協(xié)議屬于計(jì)算機(jī)網(wǎng)絡(luò)中的傳輸層協(xié)議,包括建立連接時(shí)的三次握手和斷開時(shí)的四次揮手等過程。但本書主要講的是網(wǎng)絡(luò)爬蟲相關(guān),主要爬取的是 HTTP/HTTPS 協(xié)議相關(guān)的內(nèi)容,所以這里就不再展開深入講解 TCP、IP 等相關(guān)知識了,感興趣的讀者可以搜索相關(guān)資料了解下,如《計(jì)算機(jī)網(wǎng)絡(luò)》、《圖解 HTTP》等書籍。

          3. HTTP 請求過程

          我們在瀏覽器中輸入一個(gè) URL,回車之后便會在瀏覽器中觀察到頁面內(nèi)容。

          實(shí)際上,這個(gè)過程是瀏覽器向網(wǎng)站所在的服務(wù)器發(fā)送了一個(gè)請求,網(wǎng)站服務(wù)器接收到這個(gè)請求后進(jìn)行處理和解析,然后返回對應(yīng)的響應(yīng),接著傳回給瀏覽器。

          由于響應(yīng)里包含頁面的源代碼等內(nèi)容,瀏覽器再對其進(jìn)行解析,便將網(wǎng)頁呈現(xiàn)了出來,流程如圖 1-3 所示。

          此處客戶端即代表我們自己的 PC 或手機(jī)瀏覽器,服務(wù)器即要訪問的網(wǎng)站所在的服務(wù)器。

          為了更直觀地說明這個(gè)過程,這里用 Chrome 瀏覽器開發(fā)者模式下的 Network 監(jiān)聽組件來做下演示,它可以顯示訪問當(dāng)前請求網(wǎng)頁時(shí)發(fā)生的所有網(wǎng)絡(luò)請求和響應(yīng)。

          打開 Chrome 瀏覽器,訪問百度 www.baidu.com/,這時(shí)候鼠標(biāo)右鍵并選擇“檢查”菜單(或直接按快捷鍵 F12),即可打開瀏覽器的開發(fā)者工具,如下圖所示:

          我們切換到 Network 面板,然后重新刷新網(wǎng)頁,這時(shí)候就可以看到在 Network 面板下方出現(xiàn)了很多個(gè)條目,其中一個(gè)條目就代表一次發(fā)送請求和接收響應(yīng)的過程,如圖所示:

          我們先觀察第一個(gè)網(wǎng)絡(luò)請求,即 www.baidu.com,其中各列的含義如下。

          • 第一列 Name:請求的名稱,一般會將 URL 的最后一部分內(nèi)容當(dāng)作名稱。
          • 第二列 Status:響應(yīng)的狀態(tài)碼,這里顯示為 200,代表響應(yīng)是正常的。通過狀態(tài)碼,我們可以判斷發(fā)送了請求之后是否得到了正常的響應(yīng)。
          • 第三列 Protocol:請求的協(xié)議類型,這里 http/1.1 代表是 HTTP 1.1 版本,h2 代表 HTTP 2.0 版本。
          • 第四列 Type:請求的文檔類型。這里為 document,代表我們這次請求的是一個(gè) HTML 文檔,內(nèi)容就是一些 HTML 代碼。
          • 第五列 Initiator:請求源。用來標(biāo)記請求是由哪個(gè)對象或進(jìn)程發(fā)起的。
          • 第六列 Size:從服務(wù)器下載的文件和請求的資源大小。如果是從緩存中取得的資源,則該列會顯示 from cache。
          • 第七列 Time:發(fā)起請求到獲取響應(yīng)所用的總時(shí)間。
          • 第八列 Waterfall:網(wǎng)絡(luò)請求的可視化瀑布流。

          我們點(diǎn)擊這個(gè)條目,即可看到其更詳細(xì)的信息,如圖所示。

          首先是 General 部分,其中 Request URL 為請求的 URL,Request Method 為請求的方法,Status Code 為響應(yīng)狀態(tài)碼,Remote Address 為遠(yuǎn)程服務(wù)器的地址和端口,Referrer Policy 為 Referrer 判別策略。

          再繼續(xù)往下可以看到,有 Response Headers 和 Request Headers,它們分別代表響應(yīng)頭和請求頭。請求頭里帶有許多請求信息,例如瀏覽器標(biāo)識、Cookie、Host 等信息,這是請求的一部分,服務(wù)器會根據(jù)請求頭內(nèi)的信息判斷請求是否合法,進(jìn)而作出對應(yīng)的響應(yīng)。圖 1-5 中看到的 Response Headers 就是響應(yīng)的一部分,其中包含了服務(wù)器的類型、文檔類型、日期等信息,瀏覽器接收到響應(yīng)后,會解析響應(yīng)內(nèi)容,進(jìn)而呈現(xiàn)網(wǎng)頁內(nèi)容。

          下面我們分別來介紹一下請求和響應(yīng)都包含哪些內(nèi)容。

          4. 請求(Request)

          請求,英文為 Request,由客戶端向服務(wù)器發(fā)出,可以分為 4 部分內(nèi)容:請求方法(Request Method)、請求的網(wǎng)址(Request URL)、請求頭(Request Headers)、請求體(Request Body)。

          下面我們分別予以介紹。

          請求方法(Request Method)

          請求方法,英文為 Request Method,用于標(biāo)識請求客戶端請求服務(wù)端的方式,常見的請求方法有兩種:GET 和 POST。

          在瀏覽器中直接輸入 URL 并回車,這便發(fā)起了一個(gè) GET 請求,請求的參數(shù)會直接包含到 URL 里。例如,在百度中搜索 Python,這就是一個(gè) GET 請求,鏈接為 www.baidu.com/s?wd=Python,其中 URL 中包含了請求的 query 信息,這里的參數(shù) wd 表示要搜尋的關(guān)鍵字。POST 請求大多在表單提交時(shí)發(fā)起。比如,對于一個(gè)登錄表單,輸入用戶名和密碼后,點(diǎn)擊 “登錄” 按鈕,這通常會發(fā)起一個(gè) POST 請求,其數(shù)據(jù)通常以表單的形式傳輸,而不會體現(xiàn)在 URL 中。

          GET 和 POST 請求方法有如下區(qū)別:

          • GET 請求中的參數(shù)包含在 URL 里面,數(shù)據(jù)可以在 URL 中看到;而 POST 請求的 URL 不會包含這些數(shù)據(jù),數(shù)據(jù)都是通過表單形式傳輸?shù)模瑫谡埱篌w中。
          • GET 請求提交的數(shù)據(jù)最多只有 1024 字節(jié),而 POST 方式?jīng)]有限制。

          一般來說,登錄時(shí),需要提交用戶名和密碼,其中包含了敏感信息,使用 GET 方式請求的話,密碼就會暴露在 URL 里面,造成密碼泄露,所以這里最好以 POST 方式發(fā)送。上傳文件時(shí),由于文件內(nèi)容比較大,也會選用 POST 方式。

          我們平常遇到的絕大部分請求都是 GET 或 POST 請求。另外,還有一些請求方法,如 GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE 等,我們簡單將其總結(jié)為下表。

          方  法

          描  述

          GET

          請求頁面,并返回頁面內(nèi)容

          HEAD

          類似于 GET 請求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報(bào)頭

          POST

          大多用于提交表單或上傳文件,數(shù)據(jù)包含在請求體中

          PUT

          從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定文檔中的內(nèi)容

          DELETE

          請求服務(wù)器刪除指定的頁面

          CONNECT

          把服務(wù)器當(dāng)作跳板,讓服務(wù)器代替客戶端訪問其他網(wǎng)頁

          OPTIONS

          允許客戶端查看服務(wù)器的性能

          TRACE

          回顯服務(wù)器收到的請求,主要用于測試或診斷

          本表參考:www.runoob.com/http/http-m…。

          請求的網(wǎng)址(Request URL)

          請求的網(wǎng)址,英文為 Reqeust URL,它可以唯一確定我們想請求的資源。關(guān)于 URL 的構(gòu)成和各個(gè)部分的功能我們在前文已經(jīng)提及到了,這里就不再贅述。

          請求頭(Request Headers)

          請求頭,英文為 Request Headers,用來說明服務(wù)器要使用的附加信息,比較重要的信息有 Cookie、Referer、User-Agent 等。

          下面簡要說明一些常用的頭信息:

          • Accept:請求報(bào)頭域,用于指定客戶端可接受哪些類型的信息。
          • Accept-Language:指定客戶端可接受的語言類型。
          • Accept-Encoding:指定客戶端可接受的內(nèi)容編碼。
          • Host:用于指定請求資源的主機(jī) IP 和端口號,其內(nèi)容為請求 URL 的原始服務(wù)器或網(wǎng)關(guān)的位置。從 HTTP 1.1 版本開始,請求必須包含此內(nèi)容。
          • Cookie:也常用復(fù)數(shù)形式 Cookies,這是網(wǎng)站為了辨別用戶進(jìn)行會話跟蹤而存儲在用戶本地的數(shù)據(jù)。它的主要功能是維持當(dāng)前訪問會話。例如,我們輸入用戶名和密碼成功登錄某個(gè)網(wǎng)站后,服務(wù)器會用會話保存登錄狀態(tài)信息,后面我們每次刷新或請求該站點(diǎn)的其他頁面時(shí),會發(fā)現(xiàn)都是登錄狀態(tài),這就是 Cookie 的功勞。Cookie 里有信息標(biāo)識了我們所對應(yīng)的服務(wù)器的會話,每次瀏覽器在請求該站點(diǎn)的頁面時(shí),都會在請求頭中加上 Cookie 并將其發(fā)送給服務(wù)器,服務(wù)器通過 Cookie 識別出是我們自己,并且查出當(dāng)前狀態(tài)是登錄狀態(tài),所以返回結(jié)果就是登錄之后才能看到的網(wǎng)頁內(nèi)容。
          • Referer:此內(nèi)容用來標(biāo)識這個(gè)請求是從哪個(gè)頁面發(fā)過來的,服務(wù)器可以拿到這一信息并做相應(yīng)的處理,如做來源統(tǒng)計(jì)、防盜鏈處理等。
          • User-Agent:簡稱 UA,它是一個(gè)特殊的字符串頭,可以使服務(wù)器識別客戶使用的操作系統(tǒng)及版本、瀏覽器及版本等信息。在做爬蟲時(shí)加上此信息,可以偽裝為瀏覽器;如果不加,很可能會被識別為爬蟲。
          • Content-Type:也叫互聯(lián)網(wǎng)媒體類型(Internet Media Type)或者 MIME 類型,在 HTTP 協(xié)議消息頭中,它用來表示具體請求中的媒體類型信息。例如,text/html 代表 HTML 格式,image/gif 代表 GIF 圖片,application/json 代表 JSON 類型,更多對應(yīng)關(guān)系可以查看此對照表:tool.oschina.net/commons。

          因此,請求頭是請求的重要組成部分,在寫爬蟲時(shí),大部分情況下都需要設(shè)定請求頭。

          請求體(Request Body)

          請求體,即 Request Body 一般承載的內(nèi)容是 POST 請求中的表單數(shù)據(jù),而對于 GET 請求,請求體則為空。

          例如,這里我登錄 GitHub 時(shí)捕獲到的請求和響應(yīng)如圖 1-6 所示。

          登錄之前,我們填寫了用戶名和密碼信息,提交時(shí)這些內(nèi)容就會以表單數(shù)據(jù)的形式提交給服務(wù)器,此時(shí)需要注意 Request Headers 中指定 Content-Type 為 application/x-www-form-urlencoded。只有設(shè)置 Content-Type 為 application/x-www-form-urlencoded,才會以表單數(shù)據(jù)的形式提交。另外,我們也可以將 Content-Type 設(shè)置為 application/json 來提交 JSON 數(shù)據(jù),或者設(shè)置為 multipart/form-data 來上傳文件。

          如下表是 Content-Type 和 POST 提交數(shù)據(jù)方式的關(guān)系

          Content-Type

          提交數(shù)據(jù)的方式

          application/x-www-form-urlencoded

          表單數(shù)據(jù)

          multipart/form-data

          表單文件上傳

          application/json

          序列化 JSON 數(shù)據(jù)

          text/xml

          XML 數(shù)據(jù)

          在爬蟲中,如果要構(gòu)造 POST 請求,需要使用正確的 Content-Type,并了解各種請求庫的各個(gè)參數(shù)設(shè)置時(shí)使用的是哪種 Content-Type,不然可能會導(dǎo)致 POST 提交后無法正常響應(yīng)。

          5. 響應(yīng)(Response)

          響應(yīng),即 Response,由服務(wù)器返回給客戶端,可以分為三部分:響應(yīng)狀態(tài)碼(Response Status Code)、響應(yīng)頭(Response Headers)和響應(yīng)體(Response Body)。

          響應(yīng)狀態(tài)碼(Response Status Code)

          響應(yīng)狀態(tài)碼,即 Response Status Code,表示服務(wù)器的響應(yīng)狀態(tài),如 200 代表服務(wù)器正常響應(yīng),404 代表頁面未找到,500 代表服務(wù)器內(nèi)部發(fā)生錯(cuò)誤。在爬蟲中,我們可以根據(jù)狀態(tài)碼來判斷服務(wù)器響應(yīng)狀態(tài),如狀態(tài)碼為 200,則證明成功返回?cái)?shù)據(jù),再進(jìn)行進(jìn)一步的處理,否則直接忽略。下表列出了常見的錯(cuò)誤代碼及錯(cuò)誤原因。

          常見的錯(cuò)誤代碼及錯(cuò)誤原因

          狀態(tài)碼

          說  明

          詳  情

          100

          繼續(xù)

          請求者應(yīng)當(dāng)繼續(xù)提出請求。服務(wù)器已收到請求的一部分,正在等待其余部分

          101

          切換協(xié)議

          請求者已要求服務(wù)器切換協(xié)議,服務(wù)器已確認(rèn)并準(zhǔn)備切換

          200

          成功

          服務(wù)器已成功處理了請求

          201

          已創(chuàng)建

          請求成功并且服務(wù)器創(chuàng)建了新的資源

          202

          已接受

          服務(wù)器已接受請求,但尚未處理

          203

          非授權(quán)信息

          服務(wù)器已成功處理了請求,但返回的信息可能來自另一個(gè)源

          204

          無內(nèi)容

          服務(wù)器成功處理了請求,但沒有返回任何內(nèi)容

          205

          重置內(nèi)容

          服務(wù)器成功處理了請求,內(nèi)容被重置

          206

          部分內(nèi)容

          服務(wù)器成功處理了部分請求

          300

          多種選擇

          針對請求,服務(wù)器可執(zhí)行多種操作

          301

          永久移動

          請求的網(wǎng)頁已永久移動到新位置,即永久重定向

          302

          臨時(shí)移動

          請求的網(wǎng)頁暫時(shí)跳轉(zhuǎn)到其他頁面,即暫時(shí)重定向

          303

          查看其他位置

          如果原來的請求是 POST,重定向目標(biāo)文檔應(yīng)該通過 GET 提取

          304

          未修改

          此次請求返回的網(wǎng)頁未修改,繼續(xù)使用上次的資源

          305

          使用代理

          請求者應(yīng)該使用代理訪問該網(wǎng)頁

          307

          臨時(shí)重定向

          請求的資源臨時(shí)從其他位置響應(yīng)

          400

          錯(cuò)誤請求

          服務(wù)器無法解析該請求

          401

          未授權(quán)

          請求沒有進(jìn)行身份驗(yàn)證或驗(yàn)證未通過

          403

          禁止訪問

          服務(wù)器拒絕此請求

          404

          未找到

          服務(wù)器找不到請求的網(wǎng)頁

          405

          方法禁用

          服務(wù)器禁用了請求中指定的方法

          406

          不接受

          無法使用請求的內(nèi)容響應(yīng)請求的網(wǎng)頁

          407

          需要代理授權(quán)

          請求者需要使用代理授權(quán)

          408

          請求超時(shí)

          服務(wù)器請求超時(shí)

          409

          沖突

          服務(wù)器在完成請求時(shí)發(fā)生沖突

          410

          已刪除

          請求的資源已永久刪除

          411

          需要有效長度

          服務(wù)器不接受不含有效內(nèi)容長度標(biāo)頭字段的請求

          412

          未滿足前提條件

          服務(wù)器未滿足請求者在請求中設(shè)置的其中一個(gè)前提條件

          413

          請求實(shí)體過大

          請求實(shí)體過大,超出服務(wù)器的處理能力

          414

          請求 URI 過長

          請求網(wǎng)址過長,服務(wù)器無法處理

          415

          不支持類型

          請求格式不被請求頁面支持

          416

          請求范圍不符

          頁面無法提供請求的范圍

          417

          未滿足期望值

          服務(wù)器未滿足期望請求標(biāo)頭字段的要求

          500

          服務(wù)器內(nèi)部錯(cuò)誤

          服務(wù)器遇到錯(cuò)誤,無法完成請求

          501

          未實(shí)現(xiàn)

          服務(wù)器不具備完成請求的功能

          502

          錯(cuò)誤網(wǎng)關(guān)

          服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無效響應(yīng)

          503

          服務(wù)不可用

          服務(wù)器目前無法使用

          504

          網(wǎng)關(guān)超時(shí)

          服務(wù)器作為網(wǎng)關(guān)或代理,但是沒有及時(shí)從上游服務(wù)器收到請求

          505

          HTTP 版本不支持

          服務(wù)器不支持請求中所用的 HTTP 協(xié)議版本

          響應(yīng)頭(Response Headers)

          響應(yīng)頭,即 Response Headers,包含了服務(wù)器對請求的應(yīng)答信息,如 Content-Type、Server、Set-Cookie 等。下面簡要說明一些常用的頭信息。

          • Date:標(biāo)識響應(yīng)產(chǎn)生的時(shí)間。
          • Last-Modified:指定資源的最后修改時(shí)間。
          • Content-Encoding:指定響應(yīng)內(nèi)容的編碼。
          • Server:包含服務(wù)器的信息,比如名稱、版本號等。
          • Content-Type:文檔類型,指定返回的數(shù)據(jù)類型是什么,如 text/html 代表返回 HTML 文檔,application/x-javascript 則代表返回 JavaScript 文件,image/jpeg 則代表返回圖片。
          • Set-Cookie:設(shè)置 Cookie。響應(yīng)頭中的 Set-Cookie 告訴瀏覽器需要將此內(nèi)容放在 Cookie 中,下次請求攜帶 Cookie 請求。
          • Expires:指定響應(yīng)的過期時(shí)間,可以使代理服務(wù)器或?yàn)g覽器將加載的內(nèi)容更新到緩存中。如果再次訪問時(shí),就可以直接從緩存中加載,降低服務(wù)器負(fù)載,縮短加載時(shí)間。

          響應(yīng)體(Response Body)

          響應(yīng)體,即 Response Body,這可以說是最關(guān)鍵的部分了,響應(yīng)的正文數(shù)據(jù)都在響應(yīng)體中,比如請求網(wǎng)頁時(shí),它的響應(yīng)體就是網(wǎng)頁的 HTML 代碼;請求一張圖片時(shí),它的響應(yīng)體就是圖片的二進(jìn)制數(shù)據(jù)。我們做爬蟲請求網(wǎng)頁后,要解析的內(nèi)容就是響應(yīng)體,如圖 1-7 所示。

          在瀏覽器開發(fā)者工具中點(diǎn)擊 Preview,就可以看到網(wǎng)頁的源代碼,也就是響應(yīng)體的內(nèi)容,它是解析的目標(biāo)。

          在做爬蟲時(shí),我們主要通過響應(yīng)體得到網(wǎng)頁的源代碼、JSON 數(shù)據(jù)等,然后從中做相應(yīng)內(nèi)容的提取。

          本節(jié)中,我們了解了 HTTP 的基本原理,大概了解了訪問網(wǎng)頁時(shí)背后的請求和響應(yīng)過程。本節(jié)涉及的知識點(diǎn)需要好好掌握,后面分析網(wǎng)頁請求時(shí)會經(jīng)常用到。

          6. HTTP/2.0

          前面我們也提到了 HTTP 協(xié)議從 2015 年起發(fā)布了 2.0 版本,相比 HTTP/1.1 來說,HTTP/2.0 變得更快、更簡單、更穩(wěn)定,HTTP/2.0 在傳輸層做了很多優(yōu)化,HTTP/2.0 的主要目標(biāo)是通過支持完整的請求與響應(yīng)復(fù)用來減少延遲,并通過有效壓縮 HTTP 請求頭字段將協(xié)議開銷降至最低,同時(shí)增加對請求優(yōu)先級和服務(wù)器推送的支持,這些優(yōu)化一筆勾銷了 HTTP/1.1 為做傳輸優(yōu)化想出的一系列“歪招”。

          有讀者這時(shí)候可能會問,為什么不叫 HTTP/1.2 而叫 HTTP/2.0 呢?因?yàn)?HTTP/2.0 在內(nèi)部實(shí)現(xiàn)上新的二進(jìn)制分幀層,這是沒法與之前的 HTTP/1.x 的服務(wù)器和客戶端實(shí)現(xiàn)向后兼容的,所以直接修改了主版本號為 2.0。

          下面我們就來了解下 HTTP/2.0 相比 HTTP/1.1 來說做了哪些優(yōu)化吧。

          二進(jìn)制分幀層

          HTTP/2.0 所有性能增強(qiáng)的核心就在于這個(gè)新的二進(jìn)制分幀層。在 HTTP/1.x 中,不管是請求(Request)還是響應(yīng)(Response),它們都是用文本格式傳輸?shù)模漕^部(Headers)、實(shí)體(Body)之間也是用文本換行符分隔開的。HTTP/2.0 對其做了優(yōu)化,將文本格式修改為了二進(jìn)制格式,使得解析起來更加高效。同時(shí)將請求和響應(yīng)數(shù)據(jù)分割為更小的幀,并采用二進(jìn)制編碼。

          所以這里就引入了幾個(gè)新的概念:

          • 幀:只存在于 HTTP/2.0 中的概念,是數(shù)據(jù)通信的最小單位,比如一個(gè)請求被分為了請求頭幀(Request Headers frame)和請求體/數(shù)據(jù)幀(Request Data frame)。
          • 數(shù)據(jù)流:一個(gè)虛擬通道,可以承載雙向的消息,每個(gè)流都有一個(gè)唯一的整數(shù) ID 來標(biāo)識。
          • 消息:與邏輯請求或響應(yīng)消息對應(yīng)的完整的一系列幀。

          在 HTTP/2.0 中,同域名下的所有通信都可以在單個(gè)連接上完成,該連接可以承載任意數(shù)量的雙向數(shù)據(jù)流,數(shù)據(jù)流是用于承載雙向消息的,每條消息都是一條邏輯 HTTP 消息(例如請求或響應(yīng)),它可以包含一個(gè)或多個(gè)幀。

          簡而言之,HTTP/2.0 將 HTTP 協(xié)議通信分解為二進(jìn)制編碼幀的交換,這些幀對應(yīng)著特定數(shù)據(jù)流中的消息,所有這些都在一個(gè) TCP 連接內(nèi)復(fù)用,這是 HTTP/2.0 協(xié)議所有其他功能和性能優(yōu)化的基礎(chǔ)。

          多路復(fù)用

          在 HTTP/1.x 中,如果客戶端要想發(fā)起多個(gè)并行請求以提升性能,則必須使用多個(gè) TCP 連接,而且瀏覽器位了控制資源,還會對單個(gè)域名有 6-8 個(gè) TCP 連接請求的限制。但在 HTTP/2.0 中,由于又了二進(jìn)制分幀技術(shù)的加持,HTTP/2.0 不用再以來 TCP 連接去實(shí)現(xiàn)多路并行了,客戶端和服務(wù)器可以將 HTTP 消息分解為互不依賴的幀,然后交錯(cuò)發(fā)送,最后再在另一端把它們重新組裝起來,讓我們可以:

          • 并行交錯(cuò)地發(fā)送多個(gè)請求,請求之間互不影響。
          • 并行交錯(cuò)地發(fā)送多個(gè)響應(yīng),響應(yīng)之間互不干擾。
          • 使用一個(gè)連接并行發(fā)送多個(gè)請求和響應(yīng)。
          • 不必再為繞過 HTTP/1.x 限制而做很多工作。
          • 消除不必要的延遲和提高現(xiàn)有網(wǎng)絡(luò)容量的利用率,從而減少頁面加載時(shí)間。

          這樣以來,整個(gè)數(shù)據(jù)傳輸使性能就有了極大提升:

          • 同個(gè)域名只需要占用一個(gè) TCP 連接,使用一個(gè)連接并行發(fā)送多個(gè)請求和響應(yīng),消除了因多個(gè) TCP 連接而帶來的延時(shí)和內(nèi)存消耗。
          • 并行交錯(cuò)地發(fā)送多個(gè)請求和詳情,而且之間互不影響。
          • 在 HTTP/2.0 中,每個(gè)請求都可以帶一個(gè) 31bit 的優(yōu)先值,0 表示最高優(yōu)先級, 數(shù)值越大優(yōu)先級越低。有了這個(gè)優(yōu)先值,客戶端和服務(wù)器就可以在處理不同的流時(shí)采取不同的策略,以最優(yōu)的方式發(fā)送流、消息和幀。

          流量控制

          流控制是一種阻止發(fā)送方向接收方發(fā)送大量數(shù)據(jù)的機(jī)制,以免超出后者的需求或處理能力。可以理解為,接收方已經(jīng)太繁忙了,來不及處理收到的消息了,但是發(fā)送方還在一直大量發(fā)送消息,這樣就會出現(xiàn)一些問題。

          比如說,客戶端可能請求了一個(gè)具有較高優(yōu)先級的大型視頻流,但是用戶已經(jīng)暫停視頻,客戶端現(xiàn)在希望暫停或限制從服務(wù)器的傳輸,以免提取和緩沖不必要的數(shù)據(jù)。 再比如,一個(gè)代理服務(wù)器可能具有較快的下游連接和較慢的上游連接,并且也希望調(diào)節(jié)下游連接傳輸數(shù)據(jù)的速度以匹配上游連接的速度來控制其資源利用率等等。

          由于 HTTP 是基于 TCP 實(shí)現(xiàn)的,雖然 TCP 原生有流量控制機(jī)制,但是由于 HTTP/2.0 數(shù)據(jù)流在一個(gè) TCP 連接內(nèi)復(fù)用,TCP 流控制既不夠精細(xì),也無法提供必要的應(yīng)用級 API 來調(diào)節(jié)各個(gè)數(shù)據(jù)流的傳輸。

          為了解決這一問題,HTTP/2.0 提供了一組簡單的構(gòu)建塊,這些構(gòu)建塊允許客戶端和服務(wù)器實(shí)現(xiàn)其自己的數(shù)據(jù)流和連接級流控制:

          • 流控制具有方向性。 每個(gè)接收方都可以根據(jù)自身需要選擇為每個(gè)數(shù)據(jù)流和整個(gè)連接設(shè)置任意的窗口大小。
          • 流控制基于信用。 每個(gè)接收方都可以公布其初始連接和數(shù)據(jù)流流控制窗口(以字節(jié)為單位),每當(dāng)發(fā)送方發(fā)出 DATA 幀時(shí)都會減小,在接收方發(fā)出 WINDOW_UPDATE 幀時(shí)增大。
          • 流控制無法停用。 建立 HTTP/2.0 連接后,客戶端將與服務(wù)器交換 SETTINGS 幀,這會在兩個(gè)方向上設(shè)置流控制窗口。 流控制窗口的默認(rèn)值設(shè)為 65535 字節(jié),但是接收方可以設(shè)置一個(gè)較大的最大窗口大小(2^31-1 字節(jié)),并在接收到任意數(shù)據(jù)時(shí)通過發(fā)送 WINDOW_UPDATE 幀來維持這一大小。
          • 流控制為逐躍點(diǎn)控制,而非端到端控制。 即,可信中介可以使用它來控制資源使用,以及基于自身?xiàng)l件和啟發(fā)式算法實(shí)現(xiàn)資源分配機(jī)制。

          由此可見,HTTP/2.0 提供了簡單的構(gòu)建塊實(shí)現(xiàn)了自定義策略來調(diào)節(jié)資源使用和分配,以及實(shí)現(xiàn)新傳輸能力,同時(shí)提升了網(wǎng)頁應(yīng)用的實(shí)際性能和感知性能。

          服務(wù)端推送

          HTTP/2.0 新增的另一個(gè)強(qiáng)大的新功能是,服務(wù)器可以對一個(gè)客戶端請求發(fā)送多個(gè)響應(yīng)。 換句話說,除了對最初請求的響應(yīng)外,服務(wù)器還可以向客戶端推送額外資源,而無需客戶端明確地請求。

          如果某些資源客戶端是一定會請求的,這時(shí)就可以采取服務(wù)端推送的技術(shù),在客戶端發(fā)起一次請求后,額外提前給客戶端推送必要的資源,這樣就可以相對減少一點(diǎn)延遲時(shí)間。例如,服務(wù)端可以主動把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 時(shí)再發(fā)送這些請求。

          服務(wù)端可以主動推送,當(dāng)然客戶端也有權(quán)利選擇是否接收。如果服務(wù)端推送的資源已經(jīng)被瀏覽器緩存過,瀏覽器可以通過發(fā)送 RST_STREAM 幀來拒收。

          另外主動推送也遵守同源策略,即服務(wù)器不能隨便將第三方資源推送給客戶端,而必須是經(jīng)過雙方確認(rèn)才行,這樣也能保證一定的安全性。

          HTTP/2.0 發(fā)展現(xiàn)狀

          HTTP/2.0 的普及是一件任重而道遠(yuǎn)的事情,一些主流的網(wǎng)站現(xiàn)在已經(jīng)支持了 HTTP/2.0,主流瀏覽器現(xiàn)在都已經(jīng)實(shí)現(xiàn)了 HTTP/2.0 的支持,但總的來看,目前大部分網(wǎng)站依然還是以 HTTP/1.1 為主。

          另外一些編程語言的庫還沒有完全支持 HTTP/2.0,比如對于 Python 來說,hyper、httpx 等庫已經(jīng)支持了 HTTP/2.0,但廣泛使用的 requests 庫依然還是只支持 HTTP/1.1。

          7. 總結(jié)

          本節(jié)介紹了關(guān)于 HTTP 的一些基礎(chǔ)知識,內(nèi)容不少,需要好好掌握,這些知識對于后面我們編寫和理解網(wǎng)絡(luò)爬蟲具有非常大的幫助。

          由于本節(jié)的內(nèi)容多數(shù)為概念介紹,內(nèi)容參考了很多書籍、文檔、博客,來源如下:

          • 書籍 - 《HTTP 權(quán)威指南》- 作者 David Gourley / Brian Totty
          • 文檔 - HTTP - 維基百科:en.wikipedia.org/wiki/Hypert…
          • 文檔 - HTTP - 百度百科:baike.baidu.com/item/HTTP/2…
          • 文檔 - HTTP - MDN Web Docs:developer.mozilla.org/en-US/docs/…
          • 文檔 - HTTP/2 簡介 - Google 開發(fā)文檔:developers.google.com/web/fundame…
          • 博客 - 一文讀懂 HTTP/2 及 HTTP/3 特性:blog.fundebug.com/2019/03/07/…
          • 博客 - 一文讀懂 HTTP/2 特性:zhuanlan.zhihu.com/p/26559480

          更多精彩內(nèi)容,請關(guān)注我的公眾號「進(jìn)擊的 Coder」和「崔慶才丨靜覓」。


          作者:崔慶才丨靜覓
          鏈接:https://juejin.cn/post/7081288652034146312


          主站蜘蛛池模板: 国产精品制服丝袜一区| 天美传媒一区二区三区| 亚洲熟女综合一区二区三区| jazzjazz国产精品一区二区| 一区二区视频传媒有限公司 | 欧洲精品免费一区二区三区| 无码一区二区三区在线| 国产成人无码一区二区在线播放| 国产精品合集一区二区三区| 日本一区午夜爱爱| 精品国产乱码一区二区三区| www亚洲精品少妇裸乳一区二区 | 色系一区二区三区四区五区| 韩国福利影视一区二区三区| 日韩一本之道一区中文字幕| 免费一区二区三区在线视频| 久久精品成人一区二区三区| 无码播放一区二区三区| 人妻激情偷乱视频一区二区三区| 少妇人妻偷人精品一区二区| 韩国福利视频一区二区| 四虎在线观看一区二区| 日韩最新视频一区二区三| 亚洲一区无码中文字幕| 一区二区在线视频免费观看| 精品一区二区三区在线观看l | 精品国产日产一区二区三区| 一区二区三区视频在线播放| 视频一区二区三区在线观看| 国产一区二区三区播放| 精品综合一区二区三区| 无码精品人妻一区二区三区免费 | 日韩一区二区在线观看视频| 无码国产精成人午夜视频一区二区| 国产成人精品一区二区三区无码 | 亚洲日本久久一区二区va| 国产一区二区精品| 亚洲一区二区电影| 极品尤物一区二区三区| 好吊妞视频一区二区| 无码精品人妻一区二区三区AV|