戰(zhàn)指南)
1. 重定向需求源于哪里做前端的人應(yīng)該都跟Netlify打過(guò)交道它確實(shí)是目前最省心的靜態(tài)站托管平臺(tái)之一。但很多人在部署之后才意識(shí)到一個(gè)問(wèn)題站點(diǎn)跑起來(lái)了URL卻遠(yuǎn)沒(méi)有你想的那么聽話。我在幫團(tuán)隊(duì)遷移博客、搭建落地頁(yè)、給SPA應(yīng)用配路由時(shí)遇到過(guò)太多類似的場(chǎng)景舊域名上線前需要把所有流量轉(zhuǎn)到新域名站點(diǎn)改版后一堆舊鏈接要301到新路徑前端路由用history模式刷新就404還有多個(gè)營(yíng)銷頁(yè)面需要按設(shè)備或地區(qū)做分發(fā)。這些需求全都指向同一個(gè)功能——重定向。Netlify對(duì)這一塊的支持相當(dāng)完善主要體現(xiàn)在兩種配置方式上根目錄下的_redirects文件和項(xiàng)目根目錄的netlify.toml配置文件。兩種方式各有側(cè)重用好了基本上能覆蓋日常開發(fā)中絕大多數(shù)的URL管理需求。這篇文章我會(huì)把這兩種方式從語(yǔ)法、優(yōu)先級(jí)到實(shí)戰(zhàn)逐層拆開順帶把容易踩的坑和調(diào)試手段一并講清楚。你完全可以把它當(dāng)作一份可直接查的參考手冊(cè)來(lái)用。不管你是剛接觸Netlify的獨(dú)立開發(fā)者還是正在給團(tuán)隊(duì)梳理部署規(guī)范的工程化負(fù)責(zé)人只要你需要在Netlify上管理URL行為這篇文章都值得讀完。2. 兩種配置方式弄清楚才能不踩坑2.1_redirects文件簡(jiǎn)單直接隨手可寫Netlify在構(gòu)建的時(shí)候會(huì)自動(dòng)識(shí)別發(fā)布目錄下的_redirects文件你只需要把規(guī)則一行一行地寫進(jìn)去每條規(guī)則表示一個(gè)重定向關(guān)系。基本語(yǔ)法如下從路徑 目標(biāo)路徑 狀態(tài)碼三個(gè)部分用空格分隔大概是這個(gè)意思/old-blog-post /new-blog-post 301這條規(guī)則的含義是當(dāng)用戶訪問(wèn)/old-blog-post時(shí)Netlify會(huì)返回301狀態(tài)碼永久重定向并把用戶帶到/new-blog-post。如果你用302那就是臨時(shí)重定向搜索引擎不會(huì)把權(quán)重遷移過(guò)去適合臨時(shí)促銷頁(yè)之類的場(chǎng)景。_redirects文件支持通配符這是它最方便的地方。一條規(guī)則可以覆蓋一組路徑/blog/* /news/:splat 301這里的:splat表示把*匹配到的內(nèi)容原樣傳遞到目標(biāo)地址。比如/blog/hello-world會(huì)被轉(zhuǎn)發(fā)到/news/hello-world。如果你要把整組路徑遷移到另一個(gè)域名這個(gè)通配符可以直接減少幾十條規(guī)則的書寫量。還有一點(diǎn)值得注意_redirects文件可以放在發(fā)布目錄的根目錄下也可以放在項(xiàng)目根目錄中。放在項(xiàng)目根目錄時(shí)Netlify會(huì)在構(gòu)建階段自動(dòng)將其復(fù)制到發(fā)布目錄。我更建議你把它放在項(xiàng)目根目錄因?yàn)檫@樣版本控制會(huì)一并管理它團(tuán)隊(duì)成員改起來(lái)也都有跡可循。2.2netlify.toml配置全局管理項(xiàng)目即配置如果你的團(tuán)隊(duì)已經(jīng)習(xí)慣用netlify.toml統(tǒng)一管理構(gòu)建命令、環(huán)境變量和部署分支那么重定向規(guī)則也可以直接寫進(jìn)去收斂在一處配置里。netlify.toml中的重定向配置長(zhǎng)這樣[[redirects]] from /old-path to /new-path status 301它和_redirects文件的核心功能是一致的但多了一些額外參數(shù)[[redirects]] from /old-path/* to /new-path/:splat status 200 force true headers { X-From-Netlify true }這里的status 200不是重定向而是重寫。也就是說(shuō)URL保持為/old-path/*不變但返回的是/new-path/:splat的內(nèi)容用戶地址欄不發(fā)生變化。這在做多語(yǔ)言頁(yè)面或者保留舊鏈接訪問(wèn)時(shí)很好用。force true也很好理解它可以覆蓋Netlify的默認(rèn)行為。比如你可能想對(duì)一個(gè)已經(jīng)存在的文件路徑強(qiáng)制做重定向而不希望它直接返回文件內(nèi)容加上force true就能實(shí)現(xiàn)。2.3 兩種方式的優(yōu)先級(jí)關(guān)系如果你同時(shí)使用了_redirects和netlify.toml并且規(guī)則有沖突Netlify會(huì)怎么處理這是很多人困惑的地方。Netlify官方文檔的說(shuō)明是_redirects文件的優(yōu)先級(jí)高于netlify.toml中配置的重定向規(guī)則。也就是說(shuō)當(dāng)兩條規(guī)則匹配同一個(gè)請(qǐng)求時(shí)_redirects里的規(guī)則會(huì)先生效。因此我個(gè)人的實(shí)踐建議是把最關(guān)鍵的、需要確定的規(guī)則放在_redirects里比如按域名的強(qiáng)制HTTPS跳轉(zhuǎn)、舊域名301到新域名這類全局規(guī)則而把那些跟環(huán)境、分支相關(guān)的動(dòng)態(tài)規(guī)則放在netlify.toml里。這樣兩者各司其職也不容易混亂。3. 配置優(yōu)先級(jí)與規(guī)則匹配的底層邏輯3.1 靜態(tài)文件優(yōu)先重定向次之剛開始用Netlify重定向時(shí)我最容易犯的錯(cuò)就是明明在_redirects里寫好了路徑跳轉(zhuǎn)但訪問(wèn)時(shí)總是打到原來(lái)的文件上。后來(lái)看文檔才發(fā)現(xiàn)Netlify處理請(qǐng)求的順序是這樣的檢查是否有靜態(tài)文件直接匹配該路徑。如果有直接返回文件內(nèi)容。如果沒(méi)有靜態(tài)文件再檢查是否存在匹配的重定向規(guī)則。如果都沒(méi)有才走404邏輯。這意味著如果你項(xiàng)目里真實(shí)存在/about.html文件即便你在_redirects里寫了/about /new-about 301用戶訪問(wèn)/about時(shí)也不會(huì)跳轉(zhuǎn)因?yàn)?about本身就是一個(gè)文件路徑。如果你確實(shí)想讓重定向規(guī)則優(yōu)先可以在規(guī)則后面加force標(biāo)記。在_redirects文件中是這樣寫的/about /new-about 301!注意那個(gè)結(jié)尾的感嘆號(hào)它表示“強(qiáng)制執(zhí)行重定向而不是處理靜態(tài)文件”。這在很多時(shí)候非常有用但也要謹(jǐn)慎使用。因?yàn)橐坏┘恿烁袊@號(hào)如果你的目標(biāo)地址寫錯(cuò)了用戶就會(huì)直接面對(duì)404而不是你預(yù)期的處理邏輯。對(duì)于基礎(chǔ)路徑Netlify也有一個(gè)隱藏規(guī)則它會(huì)把所有不帶斜杠的目錄路徑自動(dòng)補(bǔ)上一個(gè)斜杠再做匹配。比如請(qǐng)求/about時(shí)實(shí)際匹配的是/about/。這就引出一個(gè)常見現(xiàn)象你寫了規(guī)則/about /new-about 301但訪問(wèn)/about時(shí)卻感覺(jué)好像沒(méi)生效。其實(shí)是因?yàn)镹etlify內(nèi)部先把請(qǐng)求標(biāo)準(zhǔn)化成了/about/而你的規(guī)則寫的是無(wú)斜杠形式所以匹配不上。解決方法是把你的規(guī)則改成/about/* /new-about/:splat 301或者直接在規(guī)則里帶上斜杠去匹配。3.2 規(guī)則匹配順序誰(shuí)先寫誰(shuí)先贏Netlify的規(guī)則匹配是按順序執(zhí)行的從_redirects文件的第一行開始依次往下匹配。一旦某條規(guī)則匹配成功就會(huì)立即執(zhí)行重定向或重寫后面的規(guī)則不再參與。這個(gè)特性直接影響了你寫規(guī)則的順序。比如你有兩條規(guī)則/* /zh/home 200 /zh/* /zh/:splat 200如果你把/*寫在前面那么所有請(qǐng)求都會(huì)被重寫到/zh/home第二條規(guī)則完全沒(méi)有發(fā)揮空間。反之如果你想讓/zh/*路徑優(yōu)先走細(xì)分邏輯必須把它放在前面。有人可能會(huì)想那我把所有規(guī)則都寫得寬泛一點(diǎn)通過(guò)test來(lái)驗(yàn)證順序不就行了但在線上環(huán)境中規(guī)則的順序一旦出錯(cuò)影響的是真實(shí)用戶的訪問(wèn)。我的習(xí)慣是先寫具體規(guī)則再寫兜底規(guī)則最后才寫全局通配規(guī)則。這樣能極大降低順序錯(cuò)誤帶來(lái)的風(fēng)險(xiǎn)。3.3 一個(gè)容易忽略的細(xì)節(jié)Splat參數(shù)與查詢參數(shù)的處理通配符*和:splat是你做批量跳轉(zhuǎn)時(shí)的利器但它的匹配細(xì)節(jié)有講究。比如規(guī)則/news/* /blog/:splat 301假設(shè)用戶訪問(wèn)/news/archive/post1那么重定向后的URL是/blog/archive/post1:splat會(huì)保留完整的子路徑。這個(gè)行為很直觀但要注意如果*匹配到的內(nèi)容恰好沒(méi)有任何字符比如訪問(wèn)/news/本身那/news/其實(shí)可能匹配不上這條規(guī)則。穩(wěn)妥的做法是同時(shí)再加一條/news /blog 301把不帶子路徑的情況也覆蓋到。查詢參數(shù)的處理也值得一提。重定向規(guī)則本身默認(rèn)會(huì)保留原始請(qǐng)求的查詢參數(shù)。你從/old-page?utm_sourcetest重定向到/new-page時(shí)用戶看到的其實(shí)是/new-page?utm_sourcetest。這是符合預(yù)期的大多數(shù)時(shí)候我們不需要做什么額外處理。如果你特別想去掉某些參數(shù)那沒(méi)法用Netlify原生的重定向規(guī)則實(shí)現(xiàn)只能通過(guò)netlify.toml配合函數(shù)來(lái)處理。4. 典型場(chǎng)景實(shí)戰(zhàn)記錄4.1 SPA回退與前端路由修復(fù)SPA應(yīng)用部署到Netlify是很多人的日常操作但配置不當(dāng)最容易暴露的問(wèn)題就是刷新某個(gè)子路由時(shí)直接404。比如你的Vue或React應(yīng)用部署后訪問(wèn)/login時(shí)一切正常但一刷新頁(yè)面就變成“Page Not Found”。原因是SPA只有一個(gè)index.html入口所有路由都是由前端JS在瀏覽器端解析的服務(wù)器端并不存在/login這個(gè)文件。Netlify默認(rèn)只服務(wù)真實(shí)存在的文件找不到就404。解決方案是用一個(gè)Splat規(guī)則把未匹配的請(qǐng)求全部重寫到index.html/* /index.html 200這行配置非常有迷惑性看起來(lái)簡(jiǎn)單但以下幾個(gè)點(diǎn)決定了它是否真的好用第一這條規(guī)則必須是_redirects文件中最后一條兜底規(guī)則不能置于其他具體規(guī)則之前否則會(huì)干擾其他路徑。第二如果你部署的是帶子路徑的應(yīng)用比如應(yīng)用自身掛在/app/下則要寫成/app/* /app/index.html 200這樣才能保證其他根路徑的訪問(wèn)不被打擾。第三如果你還用了Service Worker做離線緩存那么index.html的緩存策略要特別注意否則會(huì)緩存到舊版本導(dǎo)致路由更新后刷新不到新內(nèi)容。此外如果你的SPA做了按路由拆分index.html里會(huì)引用/assets/index-xxx.js這樣帶哈希的資源文件這些路徑都是真實(shí)存在的文件所以不會(huì)被Splat規(guī)則影響到。這就是為什么兜底規(guī)則放在最后是安全的。4.2 子路徑遷移與舊域名切換站點(diǎn)改版時(shí)最頭疼的是舊鏈接全部失效搜索引擎的收錄也會(huì)受影響。用Netlify做301跳轉(zhuǎn)是標(biāo)準(zhǔn)解法而且遷移邏輯可以寫得很清晰。比如舊博客的URL結(jié)構(gòu)是/posts/2023/hello-netlify新站的URL結(jié)構(gòu)變成了/blog/hello-netlify你就可以這樣寫/posts/:year/:slug /blog/:slug 301我直接用命名占位符:year和:slug比單純的*更可讀而且:slug會(huì)精確匹配對(duì)應(yīng)的路徑段不影響后續(xù)子路徑的拼接邏輯。如果整個(gè)域名都要切換比如從old-site.com遷移到new-site.com規(guī)則可以寫成/* https://new-site.com/:splat 301!這里用301!強(qiáng)制跳轉(zhuǎn)是因?yàn)槟阆M信f域名的請(qǐng)求都直接被送到新域名哪怕請(qǐng)求本來(lái)能匹配到某個(gè)靜態(tài)文件也不能例外。這里有個(gè)細(xì)節(jié)跳轉(zhuǎn)到外部URL時(shí)協(xié)議部分必須寫全https://不能省。如果你只寫了//new-site.comNetlify會(huì)把它當(dāng)成相對(duì)路徑解析結(jié)果就是跳到//new-site.com在瀏覽器里被解析成協(xié)議相對(duì)地址看起來(lái)像http://new-site.com或者h(yuǎn)ttps://new-site.com但具體取決于當(dāng)前頁(yè)面的協(xié)議容易引起混合內(nèi)容警告。我在做舊域名遷移時(shí)一般還會(huì)順手配一個(gè)netlify.toml里的Domain規(guī)則把根域名的/.well-known一類特殊路徑排除在跳轉(zhuǎn)之外避免影響SSL證書簽發(fā)或第三方驗(yàn)證。這是很多人容易忽略的細(xì)節(jié)。4.3 多語(yǔ)言與區(qū)域分發(fā)Netlify的重定向規(guī)則是可以讀取Country、Language等請(qǐng)求頭的你可以在_redirects里寫如下規(guī)則/ /zh-cn 302 Countrycn / /en 302第一條規(guī)則的含義是當(dāng)請(qǐng)求的國(guó)家代碼為cn時(shí)訪問(wèn)首頁(yè)會(huì)302到/zh-cn。第二條是兜底規(guī)則其他地區(qū)一律跳到英文首頁(yè)。用這個(gè)思路做國(guó)際站的區(qū)域分發(fā)非常順手。而且Netlify的每個(gè)部署站點(diǎn)都默認(rèn)開啟了全球CDN請(qǐng)求頭的Country是由CDN邊緣節(jié)點(diǎn)注入的所以這個(gè)判斷是實(shí)時(shí)且準(zhǔn)確的不需要你在應(yīng)用端再做IP庫(kù)查詢。不過(guò)有一點(diǎn)要提醒Countrycn這類規(guī)則在重定向配置里的匹配值Netlify文檔中稱之為“Country code”。它使用的是ISO 3166-1 alpha-2標(biāo)準(zhǔn)例如US、DE、JP等。如果你要匹配香港地區(qū)對(duì)應(yīng)的code是HK但注意大小寫敏感寫錯(cuò)就不會(huì)生效。多語(yǔ)言站點(diǎn)的另一種做法是用URL前綴比如/zh/、/en/。這時(shí)用重寫比用重定向更適合因?yàn)槟阆M窂奖3譃?zh/about但內(nèi)容實(shí)際來(lái)自/about-zh.html之類的文件。/zh/* /:splat-zh 200這種方式在SEO上更友好因?yàn)閁RL語(yǔ)義清晰且不需要301跳轉(zhuǎn)帶來(lái)的額外流量損耗。5. 安全邊界與必須避開的坑5.1 開放重定向一個(gè)容易致命的安全隱患寫重定向規(guī)則最危險(xiǎn)的一種情況是允許用戶提供的輸入直接拼進(jìn)重定向目標(biāo)。這句話要細(xì)細(xì)拆解。假設(shè)你的站內(nèi)有一個(gè)跳轉(zhuǎn)接口本來(lái)是用來(lái)做短鏈接中轉(zhuǎn)的你可能會(huì)寫成/go/* https://example.com/:splat 301但這個(gè):splat是直接拼接在目標(biāo)URL后面的。如果使用者構(gòu)造一個(gè)類似于/go/evil.com的訪問(wèn)地址實(shí)際重定向會(huì)變成https://example.com/evil.com這倒還好。但如果規(guī)則寫得不嚴(yán)謹(jǐn)比如/go/* /redirect?url:splat 301而你的應(yīng)用代碼又沒(méi)有對(duì)url參數(shù)做域名白名單校驗(yàn)?zāi)蔷徒o釣魚攻擊開了口子。攻擊者可以構(gòu)造/go/https://evil.com誘導(dǎo)用戶點(diǎn)擊后跳轉(zhuǎn)到惡意網(wǎng)站這屬于典型的開放重定向漏洞。我自己處理這類需求時(shí)會(huì)堅(jiān)持兩個(gè)原則第一能不用用戶輸入拼目標(biāo)地址就盡量不用第二必須在應(yīng)用層加白名單校驗(yàn)不要在Netlify規(guī)則層解決所有問(wèn)題因?yàn)镹etlify的規(guī)則層沒(méi)有“允許列表”這種邏輯。如果你確實(shí)需要做一個(gè)短鏈接跳轉(zhuǎn)服務(wù)我建議用Netlify Function來(lái)寫一段校驗(yàn)邏輯而不是依賴重定向規(guī)則直接拼接。5.2 循環(huán)重定向?qū)懸?guī)則時(shí)最容易翻車循環(huán)重定向大概是最令人抓狂的線上事故之一而且它在本地測(cè)試時(shí)往往表現(xiàn)正常一旦部署到CDN就可能出問(wèn)題。一個(gè)典型的循環(huán)規(guī)則是/old-page /new-page 301 /new-page /old-page 301訪問(wèn)/old-page跳到/new-page然后再跳到/old-page瀏覽器最終會(huì)報(bào)ERR_TOO_MANY_REDIRECTS。這類問(wèn)題通常在規(guī)則數(shù)量多的時(shí)候更容易出現(xiàn)尤其是存在通配符規(guī)則時(shí)你很難一眼看出兩條規(guī)則是否互相覆蓋。避免循環(huán)重定向的核心是每寫一條規(guī)則都要在腦子里模擬一次完整請(qǐng)求鏈路。我個(gè)人的做法是維護(hù)一個(gè)“已占用路徑清單”每新增一條規(guī)則前先查一下目標(biāo)路徑是否已經(jīng)被其他規(guī)則引用為源路徑。聽起來(lái)很原始但在規(guī)則數(shù)量超過(guò)20條之后這個(gè)方法比依賴記憶可靠得多。另一個(gè)容易引發(fā)循環(huán)的場(chǎng)景是使用force或200!強(qiáng)制重寫但目標(biāo)路徑又被另一條規(guī)則重定向。比如/old/* /new/:splat 200! /new/* /elsewhere/:splat 301本來(lái)想“暗中加載/new的內(nèi)容”結(jié)果/new又被跳走訪問(wèn)者最終還是被重定向了而且行為鏈會(huì)變得難以預(yù)測(cè)。強(qiáng)制重寫和重定向并存時(shí)最好把目標(biāo)路徑徹底排除在其它重定向規(guī)則之外。5.3 動(dòng)態(tài)規(guī)則與CDN緩存配置改完但不生效許多人反饋我已經(jīng)改好了_redirects規(guī)則并重新部署但線上訪問(wèn)還是舊行為。這多半是CDN緩存導(dǎo)致的。Netlify的CDN會(huì)緩存HTTP響應(yīng)包括301、302這類重定向響應(yīng)。瀏覽器端會(huì)遵循Cache-Control頭來(lái)決定是否緩存Netlify邊緣節(jié)點(diǎn)也會(huì)按一定的TTL緩存。如果你在規(guī)則里設(shè)置了一個(gè)永久重定向301它可能會(huì)被客戶端瀏覽器長(zhǎng)期緩存即便你刪除或修改了規(guī)則用戶的瀏覽器里仍然保存著舊的跳轉(zhuǎn)結(jié)果。這正是我在規(guī)則變更之后必然提醒團(tuán)隊(duì)做一次全鏈路驗(yàn)證的原因??梢杂靡粋€(gè)無(wú)痕窗口測(cè)試或者用curl直接請(qǐng)求并觀察響應(yīng)頭curl -I https://your-site.com/old-page如果返回的狀態(tài)碼和Location頭跟你預(yù)期不一致你再去看是不是有瀏覽器緩存。CDN緩存導(dǎo)致的“不生效”其實(shí)可以通過(guò)在Netlify后臺(tái)做一次“Purge Cache”或者“Clear cache and deploy site”來(lái)解決。不要以為重新部署就代表緩存被清掉了這兩件事是分開的。這意味著線上環(huán)境的規(guī)則變更你要先清緩存再驗(yàn)證否則容易得出“配置沒(méi)生效”的錯(cuò)誤結(jié)論。6. 調(diào)試重定向的實(shí)用手段6.1 用Netlify CLI在本地調(diào)試線上調(diào)試重定向最難受的地方是任何改動(dòng)都要經(jīng)歷“代碼提交 - 部署 - CDN緩存刷新 - 驗(yàn)證”這條鏈路來(lái)回一趟至少幾分鐘遇到緩存問(wèn)題甚至要等更久。好在Netlify CLI提供了一個(gè)本地預(yù)覽功能可以模擬生產(chǎn)環(huán)境的諸多行為包括重定向規(guī)則。我通常的操作步驟是安裝CLInpm install -g netlify-cli登錄并鏈接站點(diǎn)netlify login然后netlify link啟動(dòng)本地開發(fā)服務(wù)器netlify devnetlify dev會(huì)讀取你項(xiàng)目中的netlify.toml和_redirects文件在本地啟動(dòng)一個(gè)模擬服務(wù)。這時(shí)候你可以直接訪問(wèn)localhost上的端口測(cè)試各種重定向規(guī)則是否按預(yù)期工作。這個(gè)模擬環(huán)境對(duì)規(guī)則順序、通配符匹配的還原度相當(dāng)高踩過(guò)坑之后我?guī)缀醪辉僖蕾嚒安渴鸷笤诰€驗(yàn)證”來(lái)做規(guī)則調(diào)試。還有一個(gè)比較好用的技巧在本地測(cè)試時(shí)加上curl -I看響應(yīng)頭。curl -I http://localhost:8888/old-path把Location字段看清楚你就知道瀏覽器最終會(huì)跳去哪。如果發(fā)現(xiàn)規(guī)則沒(méi)生效第一步就是檢查路徑是否帶斜杠、通配符是否拼寫正確以及是否被更靠前的規(guī)則截胡。6.2 線上日志驗(yàn)證如果問(wèn)題只在線上出現(xiàn)本地模擬無(wú)法復(fù)現(xiàn)那就要借助Netlify的Deploy Log和Edge Log去判斷。Netlify后臺(tái)的“Logs”面板里能看到邊緣側(cè)的請(qǐng)求日志包括規(guī)則命中的情況。雖然它不會(huì)明確告訴你“命中了哪一條規(guī)則”但通過(guò)狀態(tài)碼和返回路徑你可以反推出請(qǐng)求是否進(jìn)入了預(yù)期分支。比如你訪問(wèn)/about返回200且內(nèi)容是/zh/about的內(nèi)容那就說(shuō)明匹配到了一條200重寫規(guī)則。如果返回301且Location是/blog/about就說(shuō)明匹配到了301跳轉(zhuǎn)。這種反推思路適用于絕大多數(shù)排查場(chǎng)景。如果你的站點(diǎn)開啟了Netlify Analytics還可以用“Top Pages”和“Redirects”視圖觀察哪些規(guī)則被觸發(fā)得最頻繁。我一般在設(shè)定新的跳轉(zhuǎn)規(guī)則后會(huì)過(guò)一周去查看這部分?jǐn)?shù)據(jù)確認(rèn)舊鏈接的流量是否都按預(yù)期遷移完畢。6.3 規(guī)則調(diào)試速查表我在項(xiàng)目里沉淀了一個(gè)內(nèi)部用的排查表格分享出來(lái)供大家參考癥狀可能原因排查方向訪問(wèn)路徑顯示404規(guī)則未匹配到路徑大小寫不一致確認(rèn)路徑精確性檢查通配符寫法跳轉(zhuǎn)生效但URL不變配置成了200重寫而非301重定向檢查狀態(tài)碼是否為200確認(rèn)是否預(yù)期行為規(guī)則改了但線上沒(méi)變化CDN或?yàn)g覽器緩存清緩存用無(wú)痕窗口驗(yàn)證瀏覽器提示重定向過(guò)多存在循環(huán)規(guī)則逐條梳理源與目標(biāo)路徑找出互相引用特定地區(qū)訪問(wèn)落到錯(cuò)誤頁(yè)面Country匹配大小寫或code寫錯(cuò)核對(duì)ISO標(biāo)準(zhǔn)確認(rèn)規(guī)則順序舊路徑訪問(wèn)到了靜態(tài)文件靜態(tài)文件優(yōu)先級(jí)高于重定向在目標(biāo)規(guī)則末尾加感嘆號(hào)!強(qiáng)制執(zhí)行這張表不只是給新人用的我自己的經(jīng)驗(yàn)是規(guī)則過(guò)多時(shí)即使老手也容易一時(shí)腦熱漏掉某個(gè)細(xì)節(jié)。排查時(shí)按表逐項(xiàng)對(duì)照能在最短時(shí)間內(nèi)定位問(wèn)題少折騰幾輪部署。7. 規(guī)則維護(hù)的個(gè)人經(jīng)驗(yàn)最后再分享一點(diǎn)我在實(shí)際項(xiàng)目里長(zhǎng)期維護(hù)重定向規(guī)則的心得。首先給每一組規(guī)則寫清楚注釋。在_redirects文件里注釋行以#開頭不要吝嗇那幾行字。寫清楚“為什么有這個(gè)規(guī)則”、“對(duì)應(yīng)哪個(gè)舊需求”、“目標(biāo)路徑是哪次改版引入的”半年后你排查問(wèn)題時(shí)會(huì)感激當(dāng)時(shí)的自己。其次不要把無(wú)關(guān)規(guī)則堆在一個(gè)文件里。如果你的站點(diǎn)體量比較大涉及多語(yǔ)言、多版本控制、活動(dòng)頁(yè)跳轉(zhuǎn)等強(qiáng)烈建議按場(chǎng)景拆分規(guī)則用netlify.toml分塊管理而不是全部擠在_redirects里。雖然_redirects單文件寫法簡(jiǎn)單但可讀性會(huì)快速惡化規(guī)則超過(guò)30條之后你很難一眼看出每條規(guī)則的作用。再次盡量在規(guī)則里使用301而不是302作為默認(rèn)跳轉(zhuǎn)。雖然302對(duì)搜索引擎更溫和但從運(yùn)營(yíng)角度看大部分跳轉(zhuǎn)場(chǎng)景都是永久性的。而且301對(duì)SEO的權(quán)重傳遞也更有利。如果只是臨時(shí)活動(dòng)或A/B測(cè)試頁(yè)面才應(yīng)該使用302。這兩者的語(yǔ)義差異在搜索引擎眼中非常明顯弄反了會(huì)造成權(quán)重?zé)o法正確歸集。最后有一個(gè)提案值得嘗試把重定向配置納入代碼評(píng)審的流程中。重定向規(guī)則雖然不直接參與業(yè)務(wù)邏輯但它直接影響用戶體驗(yàn)和SEO屬于“改了錯(cuò)誤影響很大”的配置類型。每次變更都讓團(tuán)隊(duì)里至少另一個(gè)人review一遍能避免不少低級(jí)錯(cuò)誤。我在平常工作中見過(guò)最糟糕的重定向事故幾乎都不是因?yàn)檎Z(yǔ)法難寫而是因?yàn)橐?guī)則在不知不覺(jué)中互相覆蓋或者順序錯(cuò)亂。你只要在流程上稍微留個(gè)心眼就能避免很多不必要的線上故障。