<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【HTTP】811- 搞懂 HTTP 重定向 - 如何優(yōu)雅地使用 301

          共 6385字,需瀏覽 13分鐘

           ·

          2020-12-23 14:13

          最近一段時(shí)間,連續(xù)遇到了兩次跟重定向相關(guān)的問(wèn)題,本著知己知彼百戰(zhàn)百勝的態(tài)度,我決定深入了解一下,順便跟大家分享一下。

          作為前端開(kāi)發(fā),大家對(duì)重定向一定不陌生,不就是永久重定向和臨時(shí)重定向嘛,誰(shuí)還不知道呢 ?。

          那么大家是否知道永久重定向和臨時(shí)重定向的區(qū)別呢?如果不小心設(shè)置了永久重定向該如何取消呢?如何優(yōu)雅地使用重定向呢?接下來(lái)就讓我們來(lái)一探究竟吧。

          URL 重定向,能夠?qū)⒍鄠€(gè) URL 指向同一個(gè)頁(yè)面,這一技術(shù)有著多種用途。在 HTTP 中有一個(gè)專門(mén)的響應(yīng),叫做 HTTP 重定向,也就是所有 3 開(kāi)頭的響應(yīng)(這個(gè)相信大家都背過(guò))。

          除了 HTTP 重定向,還有其他方式能夠進(jìn)行重定向,本文也會(huì)介紹。

          內(nèi)容較長(zhǎng),我們先看一下本文的內(nèi)容架構(gòu):

          1. HTTP 重定向詳解
          2. 其他類型的重定向方式
          3. 重定向的使用場(chǎng)景
          4. 如何優(yōu)雅地使用 301

          1. HTTP 重定向

          在 HTTP 中,服務(wù)器可以通過(guò)返回一個(gè)重定向響應(yīng)來(lái)進(jìn)行重定向。這個(gè)重定向響應(yīng)有一個(gè)以 3 開(kāi)頭的狀態(tài)碼 ,并且有一個(gè) Location 頭字段 表示要重定向到的位置。

          瀏覽器接收到這個(gè)重定向之后,會(huì)立即加載 Location 中指定的 URL。通常這一過(guò)程耗時(shí)極端,用戶基本注意不到這個(gè)過(guò)程。

          重定向過(guò)程如下圖所示:


          重定向過(guò)程


          1.1 重定向狀態(tài)碼及含義

          前面提到,重定向相關(guān)的狀態(tài)碼都是以 3 開(kāi)頭的,主要有以下 9 種狀態(tài)碼:


          狀態(tài)碼狀態(tài)短語(yǔ)狀態(tài)含義
          300Multiple Choices當(dāng)請(qǐng)求的 URL 對(duì)應(yīng)有多個(gè)資源時(shí)(如同一個(gè) HTML 的不同語(yǔ)言的版本),返回這個(gè)代碼時(shí),可以返回一個(gè)可選列表,這樣用戶可以自行選擇。通過(guò) Location 頭字段可以自定首選內(nèi)容。
          301Moved Permanetly當(dāng)前請(qǐng)求的資源已被移除時(shí)使用,響應(yīng)的 Location 頭字段會(huì)提供資源現(xiàn)在的 URL。直接使用 GET 方法發(fā)起新情求。
          302Found與 301 類似,但客戶端只應(yīng)該將 Location 返回的 URL 當(dāng)做臨時(shí)資源來(lái)使用,將來(lái)請(qǐng)求時(shí),還是用老的 URL。直接使用 GET 方法發(fā)起新情求。
          303See Other用于在 PUT 或者 POST 請(qǐng)求之后進(jìn)行重定向,這樣在結(jié)果頁(yè)就不會(huì)再次觸發(fā)重定向了。
          304Not Modified資源未修改,表示本地緩存仍然可用。
          305Use Proxy用來(lái)表示必須通過(guò)一個(gè)代理來(lái)訪問(wèn)資源,代理的位置有 Location 頭字段給出
          306Switch Proxy在最新版的規(guī)范中,306 狀態(tài)碼已經(jīng)不再被使用。最初是指“后續(xù)請(qǐng)求應(yīng)使用指定的代理”。
          307Temporary Redirect與 302 類似,但是使用原請(qǐng)求方法發(fā)起新情求。
          308Permanent Redirect與 301 類似,但是使用原請(qǐng)求方法發(fā)起新情求。


          總共有 9 個(gè)與重定向相關(guān)的狀態(tài)碼,其中 301/302/304 都比較常見(jiàn),305/306 使用較少,本文不做介紹(其實(shí)我也不懂,也沒(méi)用過(guò) ?)。這 9 種狀態(tài)碼可以分成 3 大類,分別是:永久重定向、臨時(shí)重定向以及特殊重定向。

          1.2 永久重定向類

          301 和 308 都屬于永久重定向。永久重定向意味著原始 URL 不再可用,替換成了一個(gè)新的內(nèi)容。所以搜索引擎、聚合內(nèi)容閱讀器以及其他爬蟲(chóng)識(shí)別這兩個(gè)狀態(tài)碼時(shí),會(huì)更新舊 URL 的資源。

          劃重點(diǎn):這個(gè)就是永久重定向和臨時(shí)重定向的區(qū)別。

          規(guī)范中,301 本來(lái)不允許改變請(qǐng)求方法,但是已有的瀏覽器廠商都使用了 GET 方法進(jìn)行新的請(qǐng)求。所以創(chuàng)建了 308 用來(lái)處理需要使用非 GET 進(jìn)行重定向的場(chǎng)景。

          1.3 臨時(shí)重定向類

          302/303/307 都屬于臨時(shí)重定向。有時(shí),當(dāng)原有資源因?yàn)橐恍┎豢深A(yù)測(cè)的原因而臨時(shí)無(wú)法訪問(wèn)時(shí),可以通過(guò)臨時(shí)重定向的方式將請(qǐng)求轉(zhuǎn)移到另一個(gè)地方。搜索引擎和爬蟲(chóng)不應(yīng)該記住這個(gè)臨時(shí)的連接。

          此外,臨時(shí)重定向還可以用來(lái)在創(chuàng)建、修改和刪除時(shí)展示臨時(shí)的進(jìn)度頁(yè),這里通常使用 303。

          302 和 307 的關(guān)系類似于 301 和 308,參見(jiàn)上文。

          1.4 特殊重定向類

          除此之外,300/304/305/306 可以歸屬到特殊重定向類。這里重點(diǎn)說(shuō)一下 304,304 是 HTTP 緩存中的一個(gè)重要內(nèi)容,表示資源未修改,相當(dāng)于將資源重定向到本地緩存。

          關(guān)于 HTTP 緩存的詳細(xì)內(nèi)容,可以查看這篇文章:瀏覽器緩存策略之掃盲篇

          2. 其他類型的重定向方式

          HTTP 是最簡(jiǎn)易使用的重定向方式,但是有些時(shí)候我們并不能夠操作服務(wù)端。好在,除了 HTTP 重定向外,還有兩種方式:通過(guò)進(jìn)行 HTML 重定向和通過(guò) DOM 的 JS 重定向。

          2.1 HTML 重定向

          如下代碼所示,我們可以通過(guò)在元素上設(shè)置http-equiv="Refresh可以實(shí)現(xiàn)頁(yè)面的重定向。


          ??"Refresh"?content="0;?URL=https://example.com/">

          復(fù)制代碼

          content屬性需要以數(shù)字開(kāi)頭,表示多少秒之后重定向到指定頁(yè)面。通常我們?cè)O(shè)置為 0。

          注意,這一方式只適用于 HTML

          2.2 JavaScript 重定向

          這個(gè)大家都用過(guò),使用window.location可以重定向頁(yè)面。這個(gè)方法很常見(jiàn),不過(guò)多做介紹。

          當(dāng)然,這一方式只在 JavaScript 的客戶端執(zhí)行環(huán)境有效。

          上述所介紹的三種重定向方式中,按照優(yōu)先級(jí)順序如下:HTTP > HTML > JavaScript。這和我們所知道的文件的請(qǐng)求處理順序一致,不過(guò)多解釋。

          3. 重定向的使用場(chǎng)景

          不同類別的重定向有不同的使用場(chǎng)景,大致可以分為以下幾類:

          • 網(wǎng)站別名:通常情況下,對(duì)于一個(gè)資源,我們只有一個(gè) URL,但有些特殊情況下,資源會(huì)存在多個(gè) URL,這個(gè)時(shí)候就需要用到重定向。
            • 提高網(wǎng)站的可達(dá)率:比如 www.example.comexample.com都可以訪問(wèn)到指定網(wǎng)站。
            • 遷移到新的站點(diǎn):因?yàn)槟承┰蚺f站點(diǎn)被廢棄,但仍然希望之前已經(jīng)存在的連接和收藏書(shū)簽?zāi)軌蛏?,這是可以使用重定向。
            • 強(qiáng)制跳轉(zhuǎn) HTTPS:當(dāng)我們的網(wǎng)站支持 HTTPS 時(shí),通常會(huì)強(qiáng)制使用 HTTPS,所以訪問(wèn) HTTP 時(shí)需要做重定向跳轉(zhuǎn)。
          • 保證已有鏈接可用:站點(diǎn)的維護(hù)是一個(gè)長(zhǎng)時(shí)間的過(guò)程,有時(shí),我們?cè)谶M(jìn)行重構(gòu)時(shí),會(huì)對(duì)一些鏈接或路由進(jìn)行調(diào)整,這時(shí)候我們內(nèi)部的 URL 可以修改,但是對(duì)于已在被外部引用了的鏈接卻無(wú)法修改。為了保證這部分的鏈接可用,我們通常需要設(shè)置重定向。
          • 對(duì)于危險(xiǎn)操作進(jìn)行重定向:類似編輯刪除等危險(xiǎn)操作,為了避免用戶刷新時(shí)重復(fù)觸發(fā)危險(xiǎn)操作,我們可以將其重定向到臨時(shí)的進(jìn)度展示頁(yè),比如使用 303。對(duì)于耗時(shí)較長(zhǎng)的請(qǐng)求也可以這么處理。

          4. 如何優(yōu)雅地使用 301

          有些時(shí)候,我們對(duì)于永久重定向的理解并不夠,在倉(cāng)促之中使用了 301 永久重定向時(shí)就會(huì)遇到這樣的一個(gè)坑,那就是不管我們?cè)趺粗匦略O(shè)置,(有些)瀏覽器都仍然使用最開(kāi)始設(shè)置的 301 永久重定向。

          這時(shí),我們的用戶甚至是我們自己的狀態(tài)大概是這樣的:

          網(wǎng)站:忍法 - 永久重定向之術(shù) 用戶&我們:我是誰(shuí)?我在哪?我該怎么回去?

          往往在錯(cuò)誤配置了 301 之后,我們需要面臨的問(wèn)題就是取消最初的 301?

          然而,很不幸的是,似乎并沒(méi)有好的辦法能夠快速的清除用戶端已經(jīng)使用過(guò)的錯(cuò)誤 301 重定向。

          如果用戶足夠聰明的話,還可以讓用戶按照我們的說(shuō)明進(jìn)行處理。

          所以最好的做法是能夠搞懂并優(yōu)雅地使用 301,這樣才能避免這一問(wèn)題。

          下面,我們先來(lái)復(fù)現(xiàn)問(wèn)題,然后再解釋問(wèn)題。

          4.1 準(zhǔn)備:使用 Nginx 配置 301 永久重定向

          在 Nginx 中,我們可以創(chuàng)建一個(gè) server 塊來(lái)指定所有內(nèi)容都進(jìn)行重定向:

          server?{
          ?listen?80;
          ?server_name?example.com;
          ?return?301?$scheme://www.example.com$request_uri;
          }
          復(fù)制代碼

          也可以通過(guò)rewrite指令指定目錄和頁(yè)面進(jìn)行重定向:

          rewrite?^/images/(.*)$?https://images.example.com/$1?redirect;
          rewrite?^/images/(.*)$?https://images.example.com/$1?permanent;
          復(fù)制代碼

          對(duì)于其他 web 服務(wù)器,可以參考 MDN 或者網(wǎng)上的其他教程進(jìn)行配置。

          比如我準(zhǔn)備了下面這樣一個(gè) nginx.conf 文件。

          server?{
          ??listen?80;
          ??server_name?redirect.example.com;
          ??root?/your-path/web-redirect;

          ??location?/original-page?{
          ????#?下面是兩種重定向方式,為了測(cè)試使用,啟用一個(gè)即可
          ????#?永久重定向
          ????rewrite?^/original-page?http://redirect.example.com/301?permanent;
          ????#?#?臨時(shí)重定向
          ????#?rewrite?^/original-page?http://redirect.example.com/302?redirect;
          ??}

          ??location?/301?{
          ????try_files?$uri?/301.html$is_args$args;
          ??}

          ??location?/302?{
          ????try_files?$uri?/302.html$is_args$args;
          ??}
          }
          復(fù)制代碼

          301.html/302.html 自行準(zhǔn)備即可,內(nèi)容自己能區(qū)分出來(lái)就行。

          現(xiàn)在我們假設(shè)不小心將初始頁(yè)面永久重定向到了 301 頁(yè)面,現(xiàn)在想取消這一行為,臨時(shí)重定向到 302 頁(yè)面。

          1. 先開(kāi)啟永久重定向的規(guī)則,在瀏覽器訪問(wèn)http://redirect.example.com/original-page,會(huì)發(fā)現(xiàn)重定向到了 301。
          2. 關(guān)閉永久重定向規(guī)則,開(kāi)啟臨時(shí)重定向,再次訪問(wèn)初始頁(yè)面,看看是否重定向到了 302 頁(yè)面。

          至此,我們會(huì)發(fā)現(xiàn),301 之后,瀏覽器會(huì)記住第一次的 301,忽略之后的其他重定向。那這樣到底是為什么呢?

          4.2 瀏覽器會(huì)緩存“301”永久重定向

          這所以會(huì)這樣,這是因?yàn)闉g覽器會(huì)緩存“301”永久重定向。

          經(jīng)不完全測(cè)試,各瀏覽器的緩存情況如下:



          是否緩存重啟是否清除時(shí)間改為 1 年后是否失效5 年后
          Chrome未清除未失效未失效
          FireFox未清除未失效未失效
          Safari清除失效失效
          IE--(沒(méi)測(cè))------


          可以看出除了 Safari 重啟/修改時(shí)間之后,能夠使用新的重定向,Chrome/Firefox 都會(huì)無(wú)限期的緩存 301 重定向。

          在 FireFox 中我們也可以簡(jiǎn)單驗(yàn)證下,輸入about:cache,在磁盤(pán)緩存中可以找到相關(guān)的緩存項(xiàng)。如下:


          FireFox中的301緩存內(nèi)容


          瀏覽器為什么會(huì)緩存 301 重定向呢?其實(shí),HTTP RFC 中規(guī)定 301 是一個(gè)可緩存的響應(yīng),所以瀏覽器會(huì)根據(jù)響應(yīng)中的 HTTP 緩存頭進(jìn)行緩存。如果我們沒(méi)有提供明確的緩存頭,瀏覽器就會(huì)默認(rèn)永久緩存 301 響應(yīng),因?yàn)?301 是永久重定向的意思。

          這里筆者偷懶沒(méi)有測(cè)試 IE,但是鑒于有瀏覽器(Chrome/Firefox)會(huì)無(wú)限期緩存 301 重定向,那么我們就需要試著去解決這一問(wèn)題 —— 如何清除 301 重定向緩存。

          4.3 如何清除 301 重定向緩存

          內(nèi)心戲:不是說(shuō)沒(méi)法清除嗎?這怎么介紹了。我:別急,先看完。

          既然是緩存行為,那么我們就可以通過(guò)常規(guī)的緩存清理方式來(lái)處理,包括但不限于以下幾種方式:

          • 控制臺(tái)禁用緩存
          • 清除歷史記錄
          • Network 面板清除緩存

          這里大家可以自行嘗試以下,如果不行的話,記得多試 1-2 遍就行(至于為什么要多試,我也很奇怪,有的時(shí)候就是清兩遍就好了)。

          如果大家驗(yàn)證了上面的幾種清除方式,就會(huì)發(fā)現(xiàn)確實(shí)是行之有效的。那為什么我會(huì)說(shuō)沒(méi)有很好地方式去清除呢?

          大家細(xì)想,當(dāng)我們將錯(cuò)誤的 301 請(qǐng)求發(fā)布到線上環(huán)境了,并且影響了數(shù)以萬(wàn)計(jì)的用戶時(shí),我們要怎么通知并教會(huì)用戶按照我們的方式去清除緩存呢?當(dāng)然,清除歷史記錄算是最便捷的方式了,如果真的不行遇到了這種情況,那就通知用戶這么清除吧 ?。

          4.4 優(yōu)雅地使用 301

          為了避免上面需要清除的情況,最好的做法是優(yōu)雅地使用 301。

          前面解釋瀏覽器為什么會(huì)緩存 301 重定向時(shí),已經(jīng)隱晦地提到了這一方法。

          既然瀏覽器認(rèn)為這是一個(gè)可以緩存的資源,并且我們可以通過(guò)緩存頭來(lái)控制。那么在使用 301 時(shí),我們將其設(shè)置為不緩存就可以了。比如設(shè)置 Cache-Control: no-storeCache-Control: no-cache

          location?/original-page?{
          +?add_header?Cache-Control?no-store;
          ??#?永久重定向
          ??rewrite?^/original-page?http://redirect.example.com/301?permanent;
          ??#?臨時(shí)重定向
          ??#?rewrite?^/original-page?http://redirect.example.com/302?redirect;
          }
          復(fù)制代碼

          這樣設(shè)置之后,如果我們?cè)賹⒅囟ㄏ蚯袚Q成 302,會(huì)發(fā)現(xiàn)瀏覽器不會(huì)緩存 301 了,新的重定向可以立即生效了。

          總結(jié)

          以上就是重定向相關(guān)的內(nèi)容。301 使用需謹(jǐn)慎,一定要設(shè)緩存頭 ?。


          參考資料

          [1]

          維基百科 - HTTP 狀態(tài)碼:?https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81

          [2]

          MDN - Redirections in HTTP:?https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections

          [3]

          瀏覽器將 HTTP 301 緩存多長(zhǎng)時(shí)間?:?https://qastack.cn/programming/9130422/how-long-do-browsers-cache-http-301s

          [4]

          瀏覽器對(duì) 301 重定向的緩存:?https://juejin.cn/post/6844904045614743560

          [5]

          Chromium - Feature Request: I need a way to clear the 301 redirect cache:?https://bugs.chromium.org/p/chromium/issues/detail?id=633023&can=1&q=clear%20301%20redirects&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計(jì)模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(mén)(上)||?Webpack4 入門(mén)(下)
          6.?MobX 入門(mén)(上)?||??MobX 入門(mén)(下)
          7. 80+篇原創(chuàng)系列匯總

          回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~

          點(diǎn)擊“閱讀原文”查看 80+ 篇原創(chuàng)文章

          瀏覽 87
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人妻体体内射精一区二区 | 疯狂 自慰爽www看片91 国产999高清无码精品导航 | 东京热最新网址 | 中文字幕区一 | 日韩一区二区三区无码视频 |