<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # [這篇文章比我這篇講得好...](https://mp.weixin.qq.com/s?__biz=MzUyNDYxNDAyMg==&mid=2247484343&idx=1&sn=efb2f0eacc32e24ca2dd8bed0900f85e&chksm=fa2be35ecd5c6a48246107307ea838c42e807fb6ddf4838228ef552a387e0a02f0c64f1a4606&mpshare=1&scene=23&srcid=#rd) web都是基于http協議的,作為前端肯定是有必要非常的熟悉http協議。 說道http肯定會講到網絡模型,比如OSI的七層模型,TCP/IP模型,因為以前大學專業學的網絡工程,所以一提到網絡模型第一個就想到各個層啊之間的聯系啊,然后周邊什么ip地址 子網劃分 mac vlan arp ospf什么的搞得腦子有點亂因為大學也沒怎么好好學網絡專業(現在還是有點后悔)。現在我們僅僅把自己當做一名前端開發人員來寫http相關的吧。 OSI的七層模型(OSI類似于前端中的w3c 一個制定標準的)簡化為四層(有說五層將網絡接口層又細分為數據鏈路層、物理層) 現在實際應用中使用的是TCP/IP 四層的模型,最上面上的應用層、中間運輸層和網際層,下面網絡接口層。 找來一張圖,如下能很好說明: ![](https://img.kancloud.cn/71/b2/71b2455eeb976252c4c9f04294ee61b5_1006x518.png) 我們前端接觸中的http協議屬于最上層的協議,在傳輸層呢使用的是tcp協議,這個tcp協議呢是可靠的協議(有三次握手),但是速度呢逼udp慢一點點,在傳輸層中使用udp協議的多是對速度比較有需求的比如應用層請求真是IP地址的的dns在傳輸層就是使用的udp來傳輸,還有包括像QQ視頻也是采用udp(因為是不可靠的,但是最求速度)所有在網速慢的時候 會掉幀其實也就是我們的udp包掉了。 說道**tcp**,其實這個我個人覺得了解一下就好了,因為這個tcp是傳輸層的協議,僅僅是前端接觸最多的http協議在網絡模型中傳輸層采用這個tcp協議來傳輸,所以有必要了解一下,沒必要深入了解,因為就一個tcp協議都夠一本磚頭厚的書去了解了,如果不是想成CCIE的大牛還是不要浪費時間去深入何況我們只是一枚可愛的小前端,會把腦子搞暈的,下面這張圖就是三次握手的過程 ![](https://img.kancloud.cn/2b/f9/2bf9e753003809968bba25adca39ddaa_876x218.png) ## http 接下來說一下**http**,如果說tcp協議只是基于傳輸層我們可以簡單去了解一下,那么http做為上層的應用層協議,那就需要很熟悉了。 MDN的解釋可以說非常的好: > 超文本傳輸協議(HTTP)是用于傳輸諸如HTML的超媒體文檔的應用層協議。它被設計用于Web瀏覽器和Web服務器之間的通信,但它也可以用于其他目的。 HTTP遵循經典的客戶端-服務端模型,客戶端打開一個連接以發出請求,然后等待它收到服務器端響應。 HTTP是無狀態協議,意味著服務器不會在兩個請求之間保留任何數據(狀態) > HTTP報文結構 做開發抓包分析肯定是少不了,但是作為前端的話只需要關心http報文即可,所以不需要像一些cs軟件開發,裝什么wireshake什么包一股腦給你抓過來,我們只關心http的包所以其實個人覺得谷歌瀏覽器的network差不多夠我自己用了,而且報文處理過更加易讀。 打開瀏覽器 輸入網易云回車 看看http的報文如下: 請求報文頭部: ![](https://img.kancloud.cn/98/49/984975fb2b6045b8cf38ba1736904599_830x444.png) 返回的報文頭部 ![](https://img.kancloud.cn/5f/da/5fda71f77c4d9b1b689ada8e15dc56be_418x263.png) 返回的主體內容 ![](https://img.kancloud.cn/f8/c8/f8c8ba9fbe659b7a4316570d0418ddcf_819x491.png) 一般一個請求報文的格式如下: ![](https://img.kancloud.cn/c3/24/c3245040efb4ec253a2f38c22deb10d4_511x339.png) 一般一個返回報文的格式如下: ![](https://img.kancloud.cn/f0/7e/f07eb984a952bc5671f7202583e5fac9_458x330.png) 這里返回報文的狀態碼,比較常見的有4xx(找不到客戶端出錯),2xx(ok),3xx(緩存重定向),5xx(服務器的鍋T.T) #### **瀏覽器的緩存** 在想怎么寫明白瀏覽器緩存的時候檢索到一篇非常好的文章,來自一位騰訊的大牛博客的文章,寫的非常好非常的清楚,我就不獻丑了,下面直接轉載這位大牛的文章了,大牛的博客地址:www.villainhr.com 。 親,你知道緩存是什么嗎? 其實緩存就像辦健身卡,我第一次花了699辦了一年的卡之后,接下來的一年我都可以免費鍛煉。 在web 中, 我們交的不是錢,而是空間,我們耗費一定的空間之后,能夠獲得網頁打開速度質的飛躍。 當我們第一次訪問一個頁面時,我們需要交納一定的空間, 將下載的css,js,html已經img等相關資源保存在本地。 在第二次,第三次。。。訪問時,就可以不用去下載文件了。 通常來說,設置文件的緩存有兩種方式,一種是在服務器內設置響應頭文件,另外一個是使用h5的manifest文件來進行相關設置. 我們先看看報文設置響應頭的方式吧 這里的緩存分為2種,一種是強緩存,一種是協商緩存(原文沒有,我在這里補充的) ### 服務器的緩存協商 這種方式設置的緩存有兩種,一種是需要服務器驗證,另外一種是不用發送請求驗證。 ### ETag/Last-Modified 這兩種方式做法類似,都要向服務器發送一次請求進行驗證。簡直,緩存就緩存唄,為什么還要驗證呢? 其實,這是該協議的一種特有方式,發送一次驗證主要是檢查文件是否發生變化。 #### ETag ETag是用來計算文件的內容是否發生變化,比如,你在文件中刪除一個空格,這樣都算文件內容發生變化。 通常做法是用md5或者SHA1算法,計算出文件的唯一值。 在前端其實都可以完成, 找到一個文件文件解析的md5算法,然后將文件傳入,就可以得到ETag的值。 不過這里,我們著重點并不是讓你生成Etag,而是看看ETag在緩存中的重要作用。 ETag是HTTP/1.1A的一種辦法,由Web服務器生成,并寫入響應頭中。 ~~~ //response Headers ETag:"751F63A30AB5F98F855D1D90D217B356" ~~~ 接著,到了瀏覽器之后,便緩存在本地。 當下次打開同樣的文章時,會在請求頭中發送If-None-Match, 給服務器檢查文件是否發生變化。如果沒有,則告訴瀏覽器使用本地的,否則返回新文件 ~~~ //request Headers If-None-Match: "751F63A30AB5F98F855D1D90D217B356" ~~~ 通常情況下,服務器默認是打開Etag的,但是為了防止你的同事,或者后臺哥哥的后臺配置文件不正確,關閉了Etag,這時候,就需要你對對配置文件做一些設置。 這里我以Nginx為例: 打開ngnix.conf文件,檢查是否有以下語句: ~~~ etag off; more_set_headers -s 404 -t 'ETag'; more_clear_headers 'Etag'; ~~~ 如果有則將其刪除掉。然后重啟nginx就可以了。他們將Etag關閉的原因其實也很簡單,就是因為,Etag打開之后會增加服務器的負載,造成性能的局限性,所以,關閉或者打開Etag都要經過權衡的。 ### Last-Modified 這和文檔內容信息驗證不同,這里采用的是日期驗證辦法。 即,服務器上會對文件打上一個文件改動的日期,然后客戶端接受該日期,下次請求時,返回該日期,服務器驗證,如果日期未變,則告訴瀏覽器使用本地緩存即可。 即,在服務器的相應頭中,可以設置Last-Modified,來啟用這一緩存協議. ~~~ //Response Header Last-Modified:Tue, 03 Mar 2015 01:38:18 GMT ~~~ 接受到這一響應頭之后,瀏覽器會對該文件做一個緩存,并保存該日期。當下次請求的時候,會通過If-Modified-Since將日期傳入并驗證: ~~~ If-Modified-Since:Tue, 03 Mar 2015 01:38:18 GMT ~~~ 如果日期未變,則告訴瀏覽器使用緩存。 那我們通常應該怎樣啟用服務器這一功能呢? 默認情況下,服務器會對靜態資源發送Last-modified的tag。 但是,需要注意,Last-Modified的更新時間只能以秒來計,如果你文件改動過于頻繁,Last-Modified是無效的(不過,誰牛逼到1s內能多次更新文件嘞~) 實際上.Last-Modified的這個標簽的我們通常并不會單獨使用它,通常與expires結合,形成一個可降級的緩存. ### Expires/Cache-Control Expires/Cache協議與上述驗證協議最大的不同在于,他可以省略發送驗證請求環節,不需要服務器的驗證,而直接使用本地緩存。 通常這種方式,適用于,項目穩定,版本迭代不多的時候。 ### Expires 在服務器端可以設置Expires的一個絕對時間。 ~~~ //Response Headers Expires:Tue, 03 May 2016 09:33:34 GMT ~~~ 這告訴瀏覽器,在2016.5.3號之前,可以直接使用該文本的緩存副本。但是,可能會因為服務器和客戶端的GMT時間不同,會有一定的bug。 所以,這里只提議在長時間緩存的情況下使用。否則,應該選擇Cache-Control. 那在服務器端該怎么設置呢? 這里以nginx為例: ~~~ location ~* \.(?:css|js)$ { expires 1d; access_log off; add_header Cache-Control "public"; } ~~~ 通過expires設置過期時間為一天,此時,服務器會根據當前的時間,加上一天.同時添加Expires和Cache-Control頭部標簽。 即,得到的Response Header為: ~~~ Expires: Fri, 28 Feb 2014 10:42:09 GMT Cache-Control: max-age=86400 //24*60*60 (HTTP規定,如果出現max-age和expires,則max-age默認覆蓋掉expires) 當expires為負數表示no-cache,正數或零表示max-age=time。 如果你不想緩存,可以直接設置: expires -1; //永遠過期,Cache-Control: no-cache ~~~ ### Cache-Control 這應該是HTTP1.1為了解決HTTP1.0中expires的時間差的bug,而新添加的一個tag. 他的配置項很多,其實完全都可以取代expires(現在大多數服務器都支持). 引用一段原話: > Cache-Control 頭在 HTTP/1.1 規范中定義,取代了之前用來定義響應緩存策略的頭(例如 Expires)。當前的所有瀏覽器都支持 Cache-Control,因此,使用它就夠了。 > 不過,目前大部分服務器都會將兩者添加上,因為HTTP規定,如果Cache-Control和expires同時出現的話,expires會默認被覆蓋掉。 此時,返回的響應碼不再是304(文件未改動),而是200(資源成功訪問). ![](https://img.kancloud.cn/b8/6a/b86acca0f3214f10e9d1354fac360c61_651x467.png) 當前每次發送請求之前瀏覽器會檢查緩存系統里,是否有相應文件的備份,如果有的話,則直接從本地模仿一個Response頭 理論知識鋪墊完畢,我們來take a look. 看看cache-control 有哪些可以配置的屬性(以下屬性都跟在cache-control后) > public: 共有緩存,可被緩存代理服務器緩存,比如CDN > private: 私有緩存,不能被共有緩存代理服務器緩存,可被用戶的代理緩存如瀏覽器。 > max-age=[秒]:表示在這個時間范圍內緩存是新鮮的無需更新。類似Expires時間,不過這個時間是相對的,而不是絕對的。也就是某次請求成功后多少秒內緩存是新鮮的。 > s-maxage=[秒]:類似max-age, 除了僅應用于共享緩存(如代理)。 > no-cache:這里不是不緩存的意思,只是每次在使用緩存之前都強制發送請求給源服務器進行驗證,檢查文件該沒改變(其實這里和ETag/Last區別不大) > no-store:就是禁止緩存,不讓瀏覽器保留緩存副本 > must-revalidate:告訴瀏覽器,你這必須再次驗證檢查信息是否過期, 返回的代號就不是200而是304了。 > proxy-revalidate:類似must-revalidate,除了只能應用于代理緩存。 > 比如,這里我可以設置Cache-Control為: > 比如,這里我可以設置Cache-Control為: ~~~ //Response Headers Cache-Control:private, max-age=0, must-revalidate ~~~ 該文件是一個私有文件,只能被瀏覽器緩存,而不能被代理緩存。max-age標識該緩存立即過期,其實和no-cache實際上區別不大. 然后must-revalidate告訴瀏覽器,你必須給我再驗證文件過沒過期,比如接下來可能會驗證Last-Modified或者ETag.如果沒有過期則使用本地緩存. 其實上面可以直接等同于: //Response Headers Cache-Control:private,no-cache 使用no-store的結果 //Response Headers Cache-Control:no-store; 這樣表明,不管一不一樣都需要重新下載. 強烈表示,不讓你使用緩存文件。后續的就不會去驗證ETag了。 當然,如果你將IE6那種古老的瀏覽器考慮進來的話,那你干脆就做的不要臉一點,直接用下面的tag就行: Cache-Control: no-cache, no-store, must-revalidate //HTTP1.1 Pragma: no-cache //HTTP1.0 Expires: 0 //Proxy 不過現在基本上也沒有不支持Cache-Control的瀏覽器了。 常在nginx怎么配置對應的cache-control頭呢? ~~~ ##設置no-cache //Nginx expires -1; //cache-control Cache-Control:no-cache ##設置max-age=0 //Nginx expires 0; //cache-control Cache-Control:max-age=0 ##設置其他頭部 //nginx add_header Cache-Control "no-cache"; add_header Pragma no-cache; ~~~ 上面說的基本上是服務器的響應頭,那在瀏覽器的Request headers里存在cache-control代表什么呢? 當請求頭中有:Cache-Control: max-age=0,表示緩存需要進行驗證(ETag||Last-Modified),如果緩存未過期,則可以使用。 當請求頭中有:Cache-Control: no-cache,表示瀏覽器只能獲取最新的文件。 和Response Header中的no-store相對應。 ## 組合拳法之緩存策略 上面介紹的last/ETag/Expires/Cache都是HTTP協議的緩存策略。當然,緩存不止這一種,比如在HTML 4.0中定義的某些meta也可以實現自定義緩存的 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /> 但,實際情況是,這些meta只能在file:// 本地文件中使用,如果是服務器則默認被覆蓋。現在目前主流的就是使用HTTP1.1協議緩存 不過我們一般都不會單獨使用某一項。 但是,組合之后他們的效果是怎樣的呢? ![](https://img.kancloud.cn/cf/6e/cf6ebcf4152a4ed220b97d008b9a34cd_593x537.png) 如果你的網頁不是什么特別定制化的(私密)的,使用緩存能給你網站的性能帶來極大的提升。所以很推薦使用。 一個網站,說白了就是HTML+JS+CSS+fonts+img 這幾類文件(視頻就呵呵了). 我們可以針對這幾類文件做一些緩存層級 ![](https://img.kancloud.cn/b9/45/b94543042cbc5c6622d7a769d986baf0_523x219.png) 上面只是一個簡單的設置,要知道HTML是一定不能緩存的(大部分網頁)。 緩存設置時間應該在你版本穩定之后設置,否則會得不償失。 另外設置Cache-Control還可以配合ETag或者Last-Modified進行補償驗證,如果后面文件變化也可以及時反映出來。 ### 清除緩存 最常用的辦法就是修改文件的版本號,或者生成隨機文件名。 如果你只是在本地測試,想手動清楚緩存的話,可以使用. ![](https://img.kancloud.cn/db/00/db002093921507b4bd32b2535d75e151_547x197.png) 但是在Mac中不一樣,使用command+R = F5刷新, command+shift+R= ctrl+F5硬性重新加載. **另外,即使你設置了緩存策略,但是他也不會進行緩存的文件。 這些文件包括動態認證的文件,比如需要cookie驗證,輸入驗證碼等產生的文件。POST請求文件不能被緩存。** 最后補上一張圖 ![](https://img.kancloud.cn/97/e5/97e55c117d370f566c3947c201fdf540_713x573.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看