在B站看貓片被老闆發現?不如按下F12學學HTTP

文章持續更新,能夠微信搜一搜「golang小白成長記」第一時間閱讀,回覆【教程】獲golang免費視頻教程。本文已經收錄在GitHub https://github.com/xiaobaiTec... , 有大廠面試完整考點和成長路線,歡迎Star。

什麼是HTTP

HTTP 全稱超⽂文本傳輸協議,也就是HyperText Transfer Protocol。
其中咱們常見的文本,圖片,視頻這些東西均可以用超文本進行表示,而我常看的貓片,也屬於超文本,因此你們不要再說我偷偷看貓片了,我只是在看超文本。HTTP只是定義了一套傳輸超文本的規則,只要符合了這一套規則,無論你是用iphone,仍是用老爺機,均可以實現貓片的傳輸。html

七層網絡

網絡協議

大概瞭解了HTTP後,給你們看看它在它們家族裏的地位。HTTP位於應用層,跟它相似的協議還有常見的FTP協議,常見的某影天堂的下載連接曾經常常是以FTP開頭的。nginx

HTTP報文格式

有點抽象?不知道小白說的啥?那實操一下,用wireshark抓包看一下貓片裏的請求報文和響應報文具體長什麼樣子吧git

請求報文

GET /cmaskboss/164203142_30_1.enhance.webmask HTTP/1.1
Host: upos-sz-staticks3.bilivideo.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
Accept: */*
Origin: https://www.bilibili.com
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.bilibili.com/
Accept-Encoding: identity
Accept-Language: zh-CN,zh;q=0.9
Range: bytes=0-16

這上面第一行的GET 就是請求方法/cmaskboss/164203142_30_1.enhance.webmask 則是 URL , 而HTTP/1.1則是協議版本。接下來從Host開始到最後一行Range,都是Headers頭程序員

響應報文

HTTP/1.1 206 Partial Content
Content-Type: application/octet-stream
Content-Length: 17
Connection: keep-alive
Server: Tengine
ETag: "92086de1e6d1d4791fb950a0ac7e30ba"
Date: Sat, 30 Jan 2021 09:31:31 GMT
Last-Modified: Sun, 04 Oct 2020 01:54:28 GMT
Expires: Mon, 01 Mar 2021 09:31:31 GMT
Age: 1018695
Content-Range: bytes 0-16/353225
Accept-Ranges: bytes
X-Application-Context: application
x-kss-request-id: 75bcbfa8ab194e3c825e89c81a912692
x-kss-BucketOwner: MjAwMDAyMDEwNw==
X-Info-StorageClass: -
Content-MD5: kght4ebR1HkfuVCgrH4wug==
X-Cache-Status: HIT from KS-CLOUD-JH-MP-01-03
X-Cache-Status: HIT from KS-CLOUD-TJ-UN-14-13
X-Cache-Status: HIT from KS-CLOUD-LF-UN-11-25
Access-Control-Allow-Origin: https://www.bilibili.com
Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept,range
X-Cdn-Request-ID: 7e2c783ca7d392624118593ec1dc66bc

相似請求報文,HTTP/1.1協議版本206狀態碼Partial Content 則是狀態描述符。接下來從Content-Type開始到最後一行X-Cdn-Request-ID都是Headers信息github

報文信息解讀

其實上面的抓包信息,在瀏覽器裏按F12就能看到,之因此要用wireshark可能只是裝X效果比較好吧。按下F12看到的響應數據就跟下圖展現的那樣。golang

1.請求數據

2.響應數據

3.Request URL

URL是什麼

URL 表明着是統一資源定位符(Uniform Resource Locator)。做用是爲了告訴使用者 某個資源在 Web 上的地址。這個資源能夠是一個 HTML 頁面,一個 CSS 文檔,一幅圖像或一個貓片等等。上面咱們請求貓片的URL就是 https://upos-sz-staticks3.bilivideo.com/cmaskboss/164203142_30_1.enhance.webmask 這裏面細分,又能夠分爲好幾個部分。web

  • 協議部分

表示該URL的協議部分爲http仍是https,會用//爲分隔符。上面的URL表示網頁用的是HTTPS協議,而上面提到的X影天堂用的則是ftp協議的下載連接。面試

  • 域名部分

域名是upos-sz-staticks3.bilivideo.com,在發送請求前,會向DNS服務器解析IP,若是已經知道ip,還能夠跳過DNS解析那一步,直接把IP當作域名部分使用。shell

  • 端口部分

域名後面有些時候會帶有端口,和域名之間用:分隔,端口不是一個URL的必須的部分。當網址爲http://時,默認端口爲80json

當網址爲https://時,默認端口爲443,以上兩種均可以省略端口號。上面的URL其實省略了443端口號。

  • 虛擬目錄

從域名的第一個/開始到最後一個/爲止,是虛擬目錄的部分。虛擬目錄也不是URL必須的部分,本例中的虛擬目錄是/cmaskboss/

  • 文件名部分

從域名最後一個/開始到?爲止,是文件名部分;若是沒有?,則是從域名最後一個/開始到#爲止,是文件名部分;若是沒有?和#,那麼就從域名的最後一個/從開始到結束,都是文件名部分。本例中的文件名是164203142_30_1.enhance.webmask,文件名也不是一個URL的必須部分。

URL 和 URI 的區別

  • URL:Uniform Resource Locator 統一資源定位符
  • URI: Uniform Resource Identifier 統一資源標識符

其實一直有個誤解,不少人覺得URI是URL的子集,其實應該反過來。URL是URI的子集纔對。簡單解釋下。
假設"小白"(URI)是一種資源,而"在迪麗亦巴的懷裏"代表了一個位置。若是你想要找到(locate)小白,那麼你能夠到"在迪麗亦巴懷裏"找到小白,而"在迪麗亦巴懷裏的/小白"纔是咱們常說的URL。而"在迪麗亦巴懷裏的/小白"(URL)顯然是"小白"(URI)的子集,畢竟,"小白"還多是"在牛亦菲懷裏的/小白"(其餘URL)。

.jpg)

4.Request Method

HTTP 定義了一組請求方法,以代表要對給定資源執行的操做。指示針對給定資源要執行的指望動做.。雖然他們也能夠是名詞,但這些請求方法有時被稱爲HTTP動詞.。每個請求方法都實現了不一樣的語義。

此次請求B站貓片的請求裏用的是GET,意味着獲取。但其實HTTP定義了多種請求方法,來知足各類需求。除了Get,還有幾個POST、HEAD、OPTIONS、PUT、DELETE、TRACE 和 CONNECT。

常見的各個請求方法的具體功能以下:

GET

請求指定的頁面信息,並返回消息主體(body)+頭信息(header)。

HEAD:

HEAD和GET本質是同樣的,區別在於HEAD只返回頭信息(header),不返回消息主體(body)。你們不要覺得它沒用,它跟GET和POST同樣,在http/1.0的時候就存在了,實屬三元老之一了。主要用途

  • 若是想要判斷某個資源是否存在,雖然用GET也能作到,但這裏用HEAD還省下拿body的消耗,返回狀態碼200就是有404就是無
  • 若是請求的是一個比較大的資源,好比一個超大視頻和文件,你只想知道它到底有多大,而不須要整個下載下來,這時候使用HEAD請求,返回的headers會帶有文件的大小(content-lenght)。

POST

向服務器提交數據。這個方法用途普遍,幾乎目前全部的提交操做都是靠這個完成。POST跟GET最經常使用,但最大的區別在於,POST每次調用均可能會修改數據,是非冪等的,而GET相似於只讀,是冪等的。

PUT:

這個方法比較少見。在HTTP規範中POST是非等冪的,屢次調用會產生不一樣的結果。好比:建立一個用戶,因爲網絡緣由或是其餘緣由多建立了幾回,那麼將會有多個用戶被建立。而PUT id/xiaobai 則會建立一個id爲 xiaobai 的用戶,屢次調用仍是會建立的結果是同樣的,因此PUT是等冪的。可是通常爲了不形成心智負擔,實戰中也會使用POST替代PUT。

DELETE:

刪除某一個資源。基本上這個也不多見,通常實戰中若是是刪除操做,也是使用POST來替代。

OPTIONS:

options是什麼

它用於獲取當前URL所支持的方法。若請求成功,則它會在HTTP響應頭部中帶上給各類「Allow」的頭,代表某個請求在對應的服務器中都支持哪一種請求方法。好比下圖:

這裏面須要關注的點有兩個

  • Request Header裏的關鍵字段

    .jpg)

  • Response Header裏的關鍵字段

    .jpg)

Options堪稱是網絡協議中的老實人,就好像老實人剛談了個女友,每次牽手前都要問下人家 「我能夠牽你的手嗎?」, 「我能夠抱你嗎?」,獲得了答應後纔會下手。差點被這老實人氣質感動得留下了不爭氣的淚水。

何時須要使用options

跨域(記住這個詞,待會解釋)的狀況下,瀏覽器發起複雜請求前自動發起 options 請求。跨域共享標準規範要求,對那些可能對服務器數據產生反作用的 HTTP 請求方法(特別是 GET 之外的 HTTP 請求,或者搭配某些 MIME 類型的 POST 請求),瀏覽器必須首先使用 options 方法發起一個預檢請求,從而獲知服務端是否容許該跨域請求。服務器確認容許以後,才發起實際的 HTTP 請求。

這裏提到了兩個關鍵詞:

  • 跨域
  • 複雜請求

什麼是簡單請求和複雜請求。

某些請求不會觸發 CORS 預檢請求,這樣的請求通常稱爲"簡單請求",而會觸發預檢的請求則爲"複雜請求"。

  • 簡單請求

    • 請求方法爲GET、HEAD、POST
    • 只有如下Headers字段

      • Accept
      • Accept-Language
      • Content-Language
      • Content-Type
      • DPR/Downlink/Save-Data/Viewport-Width/Width (這些不常見,放在一塊兒)
    • Content-Type 只有如下三種

      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain
    • 請求中的任意 XMLHttpRequestUpload 對象均沒有註冊任何事件監聽器;
    • 請求中沒有使用 ReadableStream 對象。
  • 複雜請求

    • 不知足簡單請求的,都是複雜請求

因而可知,由於上述請求在獲取B站資源的請求Headers裏帶有 Access-Control-Request-Headers: range , 而range正好不在簡單請求的條件2中提到的Headers範圍裏,所以屬於複雜請求,因而觸發預檢options請求。

什麼是跨域

剛剛提到了一個詞叫跨域,那什麼是跨域呢?在瞭解跨域以前,首先要了解一個概念:同源。所謂同源是指,域名、協議、端口均相同

不明白不要緊,舉個例子。

須要特別注意的是,localhost和127.0.0.1雖然都指向本機,但也不屬於同源

非同源之間網頁調用就是咱們所說的跨域。在瀏覽器同源策略限制下,向不一樣發送XHR請求,瀏覽器認爲該請求不受信任,禁止請求,具體表現爲請求後不正常響應。

options帶來什麼問題

因而可知,複雜請求的條件其實很是容易知足,而一旦知足複雜請求的條件,則瀏覽器便會發送2次請求(一次預檢options,一次複雜請求),這一次options就一來一回(一個RTT),顯然會致使延遲和沒必要要的網絡資源浪費,高併發狀況下則可能爲服務器帶來嚴重的性能消耗。

.jpg)

如何優化options

每次複雜請求前都會調用一次options,這其實很是沒有必要。由於大部分時候相同的請求,短期內得到的結果是不會變的,是否能夠經過瀏覽器緩存省掉這一次查詢?

Access-Control-Max-Age就是優化這個流程中使用的一個Header。它的做用是當你每次請求options方法時,服務端返回調用支持的方法(Access-Control-Allow-Methods )和Headers(Access-Control-Allow-Headers)有哪些,同時告訴你,它在接下來 Access-Control-Max-Age時間(單位是秒)裏都支持,則這段時間內,再也不須要使用options進行請求。特別注意的是,當Access-Control-Max-Age的值爲-1時,表示禁用緩存,每一次請求都須要發送預檢請求,即用OPTIONS請求進行檢測。

5.Status Code

狀態碼是什麼

HTTP Status Code則是常說的HTTP狀態碼。當用戶訪問一個網頁時,瀏覽器會向網頁所在服務器發出請求。服務器則會根據請求做出響應,而狀態碼則是響應的一部分,表明着本次請求的結果。全部狀態碼的第一個數字表明瞭響應的大概含義,組合上第二第三個數字則能夠表示更具體的緣由。若是請求失敗了,經過這個狀態碼,大概初步判斷出此次請求失敗的緣由。如下是五類狀態碼的含義。

狀態碼流程

能夠根據如下流程圖瞭解下各種狀態碼間的關係。

  • 2xx和3xx之間的流程關係

.jpg)

  • 4xx的狀態流程

  • 5xx的狀態流程

.jpg)

常見狀態碼介紹

  • 200 OK

這是最多見的狀態碼。表明請求已成功,數據也正常返回。而B站貓片裏雖然響應成功了,但卻不是200,而是206,是爲何呢,接下去繼續看看。

  • 206 Partial Content

這個狀態碼在上面B站請求的響應結果。服務器已經成功處理了部分 GET 請求。相似於B站看視頻或者迅雷這類的 HTTP下載工具都是使用此類響應實現斷點續傳或者將一個大文檔分解爲多個下載段同時下載。

  • 307 Temporary Redirect

    內部重定向。重定向的意思是,當你輸入一個網址的時候,瀏覽器會自動幫你跳轉到另一個網址上。好比,當你在瀏覽器輸入框輸入http://www.baidu.com/時。因爲使用http並不安全,百度會自動幫你跳轉到它對應的https網頁上。而此時,須要重定向的地址,會經過Response HeadersLocation返回

  • 404 Not Found

    請求失敗,請求所但願獲得的資源未被在服務器上發現。出現這個錯誤的最有可能的緣由是服務器端沒有這個頁面,或者是Request Method與註冊URL的Method不一致,好比我有一個URL在服務端註冊的Request Method 爲 POST,但調用的時候卻錯誤用了GET,則也會出現404錯誤。

  • 499 Client has closed connection

    網絡請求過程當中,因爲服務端處理時間過長,客戶端超時。通常常見於,後端服務器處理時間過長,而客戶端也設置了一個超時等待時間,客戶端等得「不耐煩」了,主動關掉鏈接時報出。

  • 502 Bad Gateway

    服務器方面沒法給於正常的響應。通常常見於服務器崩潰後,nginx 沒法正常收到服務端的響應,給客戶端返回502狀態碼。

    .jpg)

  • 504 Gateway Timeout

    網絡請求過程當中,因爲服務端處理時間過長,網關超時。通常常見於,後端服務器邏輯處理時間過長,甚至長於 nginx設置的最長等待時間時報錯。它跟 499 狀態碼很是像,區別在於499 表示的是客戶端超時,504是網關超時。若是是499超時,能夠考慮修改客戶端的代碼調整超時時間,若是是504,則考慮調整nginx的超時配置。

    .jpg)

6. Headers

Content-Length

Content-Length是HTTP的消息長度, 用十進制數字表示。Content-Length首部指出報文中消息的當前實際字節大小。若是消息文本進行了gzip壓縮的話, Content-Length指的就是壓縮後的大小而不是原始大小。

正常狀況下Content-Length是不須要手動去設置的,大部分語言的網絡庫都會自動封裝好,可是若是在一些特殊狀況下,出現Content-Length與實際要發送的消息大小不一致,就會出現一些問題。

  • 若是Content-Length < 實際長度

    下面啓動一個HTTP服務器,全部語言都同樣,示例裏使用了golang。

    package main
    
    import (
        "fmt"
        "io/ioutil"
        "log"
        "net/http"
    )
    
    // w表示response對象,返回給客戶端的內容都在對象裏處理
    // r表示客戶端請求對象,包含了請求頭,請求參數等等
    func index(w http.ResponseWriter, r *http.Request) {
        b, _ := ioutil.ReadAll(r.Body)
        fmt.Printf("request body=%#v, content_length=%v \nheaders=%v",string(b), r.ContentLength, r.Header)
        // 往w裏寫入內容,就會在瀏覽器裏輸出
        fmt.Fprintf(w, string(b))
    }
    
    func main() {
        // 設置路由,若是訪問/,則調用index方法
        http.HandleFunc("/", index)
    
        // 啓動web服務,監聽9090端口
        err := http.ListenAndServe(":9999", nil)
        if err != nil {
            log.Fatal("ListenAndServe: ", err)
        }
    }

    在控制檯輸入

    $ $ curl -L -X POST 'http://127.0.0.1:9999' -H 'Content-Type: application/json' -H 'Content-Length: 5' -d '1234567' |  jq
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    12  100     5  100     7    828   1160 --:--:-- --:--:-- --:--:--  1400
    12345

    輸入的body是 1234567,共7個數字,可是輸入的 Content-Length爲 5。到了服務器那,收到了 12345,共5個數字,數量上跟輸入的Content-Length一致。 因而可知當Content-Length < 實際長度, 消息會被截斷。

  • 若是Content-Length > 實際長度

    仍是上面的服務端代碼,可是控制檯輸入如下命令

    $ curl -L -X POST 'http://127.0.0.1:9999' -H 'Content-Type: application/json' -H 'Content-Length: 100' -d '1234567' | jq
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100     7    0     0    0     7      0      0 --:--:--  0:01:19 --:--:--     0

    此次狀況不太同樣,會發現請求一直阻塞沒有返回。這是由於輸入的body是 1234567,共7個數字,可是輸入的 Content-Length爲 100。也就是服務端一直認爲此次的body長度爲100,可是目前只收到了部分消息(長度爲7),剩餘的長度爲93的消息因爲各類緣由還在路上,所以選擇傻傻等待剩下的消息,就形成了上面提到的阻塞。

Range

視頻播放須要支持用戶調整播放進度,支持讓用戶選擇直接跳到中間部分開始播放。爲了實現這個功能,須要經過HTTP Range Requests 協議用於指定須要獲取視頻片斷。而 Request Header裏的range頭則是用於指定要請求文件的起始和結束位置。

  • 若是服務器支持 Range Requests 協議,會讀取視頻文件,並將他的第 162653~242638 字節提取出來,並以狀態碼 206 響應請求。

  • 若是服務器不支持,直接忽略 Range 頭,讀取整個文件內容,以狀態碼 200 響應便可。
  • 當咱們在 html 中放一個 video 標籤,瀏覽器會直接發起一個 Range: bytes=0- 的請求,向服務器請求從開始到結尾的完整文件

    • 若是服務器不支持 Range Requests,響應碼爲 200,瀏覽器會正常按流式加載整個視頻文件;
    • 若是服務器支持 Range Requests,響應碼爲 206,則瀏覽器會在接收到足夠字節(好比當前播放進度日後推20s)時結束掉請求,以節省網絡流量;當播放進度繼續往前,緩存不夠時,瀏覽器會發起一個新的 Range Requests 請求,請求的 Range 直接從緩存結尾的字節開始,只加載剩餘的部分文件。
  • 同時返回的Response Headers中有一個 content-range 的字段域,用於告訴了客戶端發送了多少數據。content-range 描述了響應覆蓋的範圍和整個實體長度。通常格式:Content-Range: 開始字節位置-結束字節位置/文件大小(byte)

Connection

長鏈接和短鏈接

  • Connection: close

    表示請求響應完成以後當即關閉鏈接,這是HTTP/1.0請求的默認值。每次請求都通過「建立tcp鏈接 -> 請求資源 -> 響應資源 -> 釋放鏈接」這樣的過程

  • Connection: keep-alive

    表示鏈接不當即關閉,能夠繼續響應下一個請求。HTTP/1.1的請求默認使用一個持久鏈接。能夠作到只創建一次鏈接,屢次資源請求都複用該鏈接,完成後關閉。流程上是 創建tcp鏈接 -> 請求資源 -> 響應資源 -> ... (保持鏈接)... -> 第n次請求資源 -> 第n次響應資源 -> 釋放鏈接。

在http1.1中Request Header和Reponse Header中都有可能出現一個Connection: keep-alive 頭信息。Request Header裏的Connection: keep-alive 頭是爲了告訴服務端,客戶端想要以長鏈接形式進行通訊。而Response Header裏的Connection: keep-alive 頭是服務端告訴客戶端,個人服務器支持以長鏈接的方式進行通訊。若是不能使用長鏈接,會返回 Connection: close ,至關於告訴客戶端「我不支持長鏈接,你死了這條心,老老實實用短鏈接吧」 。

HTTP爲何要使用長鏈接

咱們知道 HTTP 創建在 TCP 傳輸層協議之上,而 TCP 的創建須要三次握手,關閉須要四次揮手,這些步驟都須要時間,帶給 HTTP 的就是請求響應時延。若是使用短鏈接,那麼每次數據傳輸都須要經歷一次上面提到的幾個步驟,若是能只鏈接一次,保持住這個鏈接不斷開,期間通訊就能夠省下創建鏈接和斷開鏈接的過程,對於提高HTTP性能有很大的幫助。

  • 能夠看到,在使用 Connection: close 通訊時,每次都須要從新經歷一次握手揮手。能夠經過 Connection: keep-alive 省下這部分的資源消耗。

  • 長鏈接能夠省去較多的TCP創建和關閉的操做,減小浪費,節約時間。對於頻繁請求資源的客戶來講,較適用長鏈接。可是在長鏈接的應用場景下,須要有一方主動關閉鏈接。若是客戶端和服務端之間的鏈接一直不關閉的話,鏈接數則會愈來愈多,嚴重的時候會形成資源佔用太高。
  • 解決方案也比較簡單。若是這些鏈接其實長時間內並無任何數據傳輸的話,那其實屬於空閒鏈接,這時候能夠在服務端設置空閒鏈接的存活時間,超過必定時間後由服務端主動斷掉,從而保證無用鏈接及時釋放。

Cookies

Cookies是什麼

  1. Cookie 是瀏覽器訪問服務器後,服務器傳給瀏覽器的一段數據。裏面通常帶有該瀏覽器的身份信息。
  2. 瀏覽器須要保存這段數據,不得輕易刪除。
  3. 此後每次瀏覽器訪問該服務器,都必須帶上這段數據。服務器用使用這段數據確認瀏覽器身份信息。

Cookie的做用

Cookie 通常有兩個做用。

  • 識別用戶身份。

    • 舉個例子。用戶 A 用瀏覽器訪問了「貓貓網」,「貓貓網」的服務器就會馬上給 A 返回一段Cookie數據,內含「uid=a」。
    • 當 A 再次訪問「貓貓網」下的其餘頁面時,好比跳轉到「貓貓交友評論」,就會附帶上「uid=a」這段數據。
    • 同理,用戶 B 用瀏覽器訪問「貓貓網」 時,就給 B 分配了一段Cookie數據,內含「uid=b」。B 以後訪問「貓貓網」的時候,就會一直帶上「uid=b」這段數據。
    • 所以「貓貓網」的服務器經過Cookie數據就能區分 A 和 B 兩個用戶了。
  • 持久化用戶信息。

    • 由於cookies的數據會被用戶瀏覽器保存到本地下。所以能夠利用這一特色保持一些簡單的用戶數據。
    • 好比一些博客網站,能夠經過cookies記錄下用戶的性別年齡等信息,以此進行一些個性化展現。
    • 固然上面提到的都是一些比較粗糙的場景,是爲了方便你們理解cookies的功能。實際使用cookies會很是謹慎。

Referrer Policy 和 Referrer

Referrer是什麼

Referrer 是HTTP請求header的報文頭,用於指明當前流量的來源參考頁面,常被用於分析用戶來源等信息。經過這個信息,咱們能夠知道訪客是怎麼來到當前頁面的。好比在上面的請求截圖裏,能夠看出我是使用https://www.bilibili.com/訪問的視頻資源。

Referrer Policy 是什麼

  • Referrer 字段,會用來指定該請求是從哪一個頁面跳轉頁來的,裏面的信息是瀏覽器填的。
  • 而 Referrer Policy 則是用於控制Referrer信息傳不傳、傳哪些信息、在何時傳的策略。

爲何要這麼麻煩呢?由於有些網站一些用戶敏感信息,好比 sessionid 或是 token 放在地址欄裏,若是當作Referrer字段所有傳遞的話,那第三方網站就會拿到這些信息,會有必定的安全隱患。因此就有了 Referrer Policy,用於過濾 Referrer 報頭內容。

好比在上面的請求截圖裏,能夠看出我是使用strict-origin-when-cross-origin策略,含義是跨域時將當前頁面URL過濾掉參數及路徑部分,僅將協議、域名和端口(若是有的話)看成 Referrer。不然 Referrer 仍是傳遞當前頁的全路徑。同時當發生降級(好比從 https:// 跳轉到 http:// )時,不傳遞 Referrer 報頭。

Cache-control

什麼是cache-control

cache-control,用於控制瀏覽器緩存。簡而言之,當某人訪問網站時,其瀏覽器將在本地保存某些資源,例如圖像和網站數據。當該用戶從新訪問同一網站時,緩存控制設置的規則會肯定該用戶是否從本地緩存中加載這些資源,或者瀏覽器是否必須向服務器發送新資源的請求。

什麼是瀏覽器緩存

瀏覽器緩存是指瀏覽器本地保存網站資源,以便沒必要再次經過網絡從服務器獲取它們。例如,「貓貓網」的背景圖像能夠保存到本地緩存中,這樣在用戶第二次訪問該頁面時,該圖像將從用戶的本地文件加載,剩下網絡獲取資源的時間,頁面加載速度就會更快。

可是瀏覽器也不會永遠把這些網站資源放在本地,不然本地磁盤就會炸,因此會限定保存資源的時間,這叫生存時間(TTL)。若是 TTL 過時後用戶請求緩存的資源,瀏覽器必須再次經過網絡與服務器創建鏈接並從新下載這個資源。

常見的緩存控制策略

  • cache-control: private
    具備「private」指令的響應只能由客戶端緩存,不能由中間代理(例如 CDN或代理)緩存。這些資源一般是包含私密數據的資源,例如顯示用戶我的信息的網站。
  • cache-control: public
    相反,「public」指令表示資源能夠由任何緩存存儲。
  • cache-control: no-store
    帶有「no-store」指令的響應沒法緩存到任何位置,也永不緩存。也就是說,用戶每次請求此數據時,都必須將請求發送到源站服務器以獲取新副本。此指令一般保留給包含極其敏感數據的資源,例如銀行賬戶信息。
  • cache-control: max-age
    此指令指定了生存時間,也就是資源在下載後能夠緩存多少秒鐘。例如,若是將最大期限設置爲 1800,則首次從服務器請求資源後的 1800 秒(30 分鐘)內,後續請求都會向用戶提供該資源的緩存版本。若是 30 分鐘後用戶再次請求資源,則客戶端須要向服務器從新請求該資源。
  • cache-control: no-cache

    從B站截圖裏能夠看出,使用的緩存控制指令是cache-control: no-cache。它表示,只有先檢查資源沒有更新版本後,纔可以使用所請求資源的緩存版本。那麼問題來了,怎麼判斷資源是否有更新版本呢?這就須要 ETag

ETag

Etag是 Entity tag的縮寫,是服務端的一個資源版本的令牌標識。在 HTTP 響應頭中將其傳送到客戶端。每當資源更新時,此令牌會源站服務器上更改。

  • 好比,瀏覽器第一次請求資源的時候,服務端返回了這個資源的ETag: "095933fff2323351d3b495f2f879616f1762f752"
  • 當瀏覽器再次請求這個資源的時候,瀏覽器會將If-None-Match: "095933fff2323351d3b495f2f879616f1762f752" 傳輸給服務端,服務端拿到該ETAG,對比資源是否發生變化。

    • 若是資源未發生改變,則返回304HTTP狀態碼,不返回具體的資源。
    • 不然表示資源已經更新,瀏覽器須要下載新版本以提供給用戶。
  • 此過程可確保用戶始終得到資源的最新版本,而且無需進行沒必要要的下載。

最後

果真B站是個充滿學習氛圍的地方,看個貓片都能學到這麼多硬核知識。接下來我打算去舞蹈區看看有沒有適合大家的知識點。

我是小白,有空?一塊兒在知識的海洋裏嗆水啊,懂我意思?

參考資料

- [1] 計算機網絡自動向下

- [2] 極客時間-趣談網絡協議

- [3] 極客時間-透視HTTP

- [4] 圖解HTTP

- [5] 漫畫形象-小肥柴

文章推薦:

相關文章
相關標籤/搜索