HTTP 狀態(tài)碼有哪些?該怎么用?
回復(fù)交流,加入前端編程面試算法每日一題群
引言
本文從以下幾個(gè)方面,循序漸進(jìn)走進(jìn) HTTP 狀態(tài)碼
狀態(tài)碼用來做什么的 常見狀態(tài)碼有哪些 容易爭(zhēng)論的點(diǎn)
狀態(tài)碼用來做什么的
HTTP 狀態(tài)行中使用狀態(tài)碼(Status Code)和原因短語(Reason Phrase)來簡(jiǎn)單描述請(qǐng)求的結(jié)果

Version:版本號(hào),例如 HTTP/2 Reason:是狀態(tài)碼的簡(jiǎn)短文字描述,例如“OK”“Not Found”等等,也可以自定義,它其實(shí)對(duì)狀態(tài)碼的解釋說明 Status Code:狀態(tài)碼,表示服務(wù)器對(duì)請(qǐng)求的處理結(jié)果
這里我們重點(diǎn)介紹狀態(tài)碼,狀態(tài)碼是用以表示 HTTP 響應(yīng)狀態(tài)的 3 位數(shù)字代碼,由RFC 2616規(guī)范定義。 合理的狀態(tài)碼不僅可以讓用戶或者瀏覽器做出更加合適的進(jìn)一步操作(例如繼續(xù)發(fā)送請(qǐng)求、切換協(xié)議,重定向跳轉(zhuǎn)等),而且可以讓客戶端代碼更加易于理解和維護(hù) 。
RFC 把狀態(tài)碼分成五類,分別是:
1××: 請(qǐng)求已被接受正被處理,表示目前是協(xié)議處理的中間狀態(tài),還需要后續(xù)的操作 2××: 請(qǐng)求成功處理,報(bào)文已經(jīng)收到并被正確處理 3××: 代表需要客戶端采取進(jìn)一步的操作才能完成請(qǐng)求,例如重定向,通常,這些狀態(tài)碼用來重定向,后續(xù)的請(qǐng)求地址(重定向目標(biāo))在本次響應(yīng)的Location域中指明 4××: 客戶端錯(cuò)誤,請(qǐng)求報(bào)文有誤,服務(wù)器無法處理 5××: 服務(wù)器錯(cuò)誤,服務(wù)器在處理請(qǐng)求時(shí)內(nèi)部發(fā)生了錯(cuò)誤
常見狀態(tài)碼有哪些
1xx
1xx 是很陌生的,代表請(qǐng)求已被接受,需要繼續(xù)處理。這類響應(yīng)是臨時(shí)響應(yīng),標(biāo)示客戶應(yīng)該等待服務(wù)器采取進(jìn)一步行動(dòng)。
我們最常見的是 101(Switching Protocols)
101(Switching Protocols)
服務(wù)器已經(jīng)理解了客戶端的請(qǐng)求,并根據(jù) Upgrade 消息頭切換協(xié)議。
在 http header怎么判斷協(xié)議是不是websocket 我們提到過,http 發(fā)送請(qǐng)求給服務(wù)器,服務(wù)器通過判斷 header 中是否包含 Connection: Upgrade 與 Upgrade: websocket 來判斷當(dāng)前協(xié)議是否要升級(jí)到 websocket ,如果服務(wù)器同意進(jìn)行 WebSocket 連接時(shí),返回響應(yīng)碼 101

2xx
表示請(qǐng)求已成功被服務(wù)器接收、理解、并接受
常見的有
200 204 206:
200(OK)
最常見的,表示請(qǐng)求成功
204(NO Content)
與 200 基本相同,但響應(yīng)頭后沒有 body 數(shù)據(jù)
206(Partial Content)
分片傳輸,每次只返回了請(qǐng)求資源的 部分 ,常用于實(shí)現(xiàn)斷點(diǎn)續(xù)傳或者將一個(gè)大文檔分解為多個(gè)下載段同時(shí)下載
請(qǐng)求頭中包含 Range 字段時(shí),響應(yīng)需要只返回 Range 指定的那一段。響應(yīng)中應(yīng)包含 Content-Range 來指示返回內(nèi)容的范圍
例如:
'Range':byte=5001-10000
// 表示本次要請(qǐng)求資源的5001-10000字節(jié)的部分
這種情況下,如果服務(wù)器接受范圍請(qǐng)求并且成功處理,就會(huì)返回 206 ,并且在響應(yīng)的頭部返回
'Content-Range':bytes 5001-10000/10000
// 表示整個(gè)資源有10000字節(jié),本次返回的范圍為 5001-10000字節(jié)
3xx
這類狀態(tài)碼代表需要客戶端采取進(jìn)一步的操作才能完成請(qǐng)求。通常,這些狀態(tài)碼用來重定向, 重定向目標(biāo)在本次響應(yīng)的 Location 頭字段中指明
主要有以下 9 種狀態(tài)碼:
| 狀態(tài)碼 | 狀態(tài)短語 | 狀態(tài)含義 |
|---|---|---|
| 300 | Multiple Choices | 當(dāng)請(qǐng)求的 URL 對(duì)應(yīng)有多個(gè)資源時(shí)(如同一個(gè) HTML 的不同語言的版本),返回這個(gè)代碼時(shí),可以返回一個(gè)可選列表,這樣用戶可以自行選擇。通過 Location 頭字段可以自定首選內(nèi)容。 |
| 301 | Moved Permanetly | 當(dāng)前請(qǐng)求的資源已被移除時(shí)使用,響應(yīng)的 Location 頭字段會(huì)提供資源現(xiàn)在的 URL。直接使用 GET 方法發(fā)起新情求。 |
| 302 | Found | 與 301 類似,但客戶端只應(yīng)該將 Location 返回的 URL 當(dāng)做臨時(shí)資源來使用,將來請(qǐng)求時(shí),還是用老的 URL。直接使用 GET 方法發(fā)起新情求。 |
| 303 | See Other | 用于在 PUT 或者 POST 請(qǐng)求之后進(jìn)行重定向,這樣在結(jié)果頁就不會(huì)再次觸發(fā)重定向了。 |
| 304 | Not Modified | 資源未修改,表示本地緩存仍然可用。產(chǎn)生這個(gè)狀態(tài)的前提是:客戶端本地已經(jīng)有緩存的版本,并且在 Request 中告訴了服務(wù)端,當(dāng)服務(wù)端通過時(shí)間或者 Etag,發(fā)現(xiàn)沒有更新的時(shí)候,就會(huì)返回一個(gè)不含 body 的 304 狀態(tài) |
| 305 | Use Proxy | 用來表示必須通過一個(gè)代理來訪問資源,代理的位置有 Location 頭字段給出 |
| 306 | Switch Proxy | 在最新版的規(guī)范中,306 狀態(tài)碼已經(jīng)不再被使用。最初是指“后續(xù)請(qǐng)求應(yīng)使用指定的代理”。 |
| 307 | Temporary Redirect | 與 302 類似,但是使用原請(qǐng)求方法發(fā)起新情求。 |
| 308 | Permanent Redirect | 與 301 類似,但是使用原請(qǐng)求方法發(fā)起新情求。 |
這 9 種狀態(tài)碼可以分成 3 大類,分別是:永久重定向、臨時(shí)重定向以及特殊重定向
永久重定向: 301 、 308 臨時(shí)重定向: 302、303、307 特殊重定向: 300、304、305、306
永久重定向
301 和 308 都屬于永久重定向,301 本來在規(guī)范中是不允許重定向時(shí)改變請(qǐng)求方法的(將POST改為GET),但是許多瀏覽器卻允許重定向時(shí)改變請(qǐng)求方法(這是一種不規(guī)范的實(shí)現(xiàn))
308 的出現(xiàn)也是給上面的行為做個(gè)規(guī)范,不過是不允許重定向時(shí)改變請(qǐng)求方法。
| Permanent | Temporary | |
|---|---|---|
| Allows changing the request method from POST to GET. | 301 | 302 |
| Does not allow changing the request method from POST to GET. | 308 | 307 |
臨時(shí)重定向
302、303、307 都屬于臨時(shí)重定向,臨時(shí)是指訪問的資源可能暫時(shí)先用location的URI訪問,但舊資源還在的,下次你再來訪問的時(shí)候可能就不用重定向了
302 和 307 的關(guān)系類似于 301 和 308,303通常用來在創(chuàng)建、修改和刪除時(shí)展示臨時(shí)的進(jìn)度頁
特殊重定向
除此之外,300/304/305/306 可以歸屬到特殊重定向類。這里重點(diǎn)說一下 304,304 是 HTTP 緩存中的一個(gè)重要內(nèi)容,表示資源未修改,相當(dāng)于將資源重定向到本地緩存。
304 又是一個(gè)每個(gè)前端必知必會(huì)的狀態(tài),產(chǎn)生這個(gè)狀態(tài)的前提是:客戶端本地已經(jīng)有緩存的版本,并且在 Request 中告訴了服務(wù)端,當(dāng)服務(wù)端通過時(shí)間或者 Etag,發(fā)現(xiàn)沒有更新的時(shí)候,就會(huì)返回一個(gè)不含 body 的 304 狀態(tài)
4xx
表示客戶端發(fā)送的請(qǐng)求報(bào)文有誤,服務(wù)器無法處理,它就是真正的“錯(cuò)誤碼”含義了
400(Bad Request)
由于明顯的客戶端錯(cuò)誤(例如,格式錯(cuò)誤的請(qǐng)求語法,太大的大小,無效的請(qǐng)求消息或欺騙性路由請(qǐng)求),服務(wù)器不能或不會(huì)處理該請(qǐng)求
403(Forbidden)
表示服務(wù)器禁止訪問資源。原因可能多種多樣,例如信息敏感、法律禁止等,如果服務(wù)器友好一點(diǎn),可以在 body 里詳細(xì)說明拒絕請(qǐng)求的原因,不過現(xiàn)實(shí)中通常都是直接給一個(gè)“閉門羹”
404(Not Found)
請(qǐng)求失敗,請(qǐng)求所希望得到的資源未在服務(wù)器上發(fā)現(xiàn),但允許用戶的后續(xù)請(qǐng)求。
5xx
服務(wù)器錯(cuò)誤,服務(wù)器在處理請(qǐng)求時(shí)內(nèi)部發(fā)生了錯(cuò)誤
500(Internal Server Error)
通用錯(cuò)誤消息,服務(wù)器遇到了一個(gè)未曾預(yù)料的狀況,導(dǎo)致了它無法完成對(duì)請(qǐng)求的處理。沒有給出具體錯(cuò)誤信息。
501(Not Implemented)
服務(wù)器不支持當(dāng)前請(qǐng)求所需要的某個(gè)功能。當(dāng)服務(wù)器無法識(shí)別請(qǐng)求的方法,并且無法支持其對(duì)任何資源的請(qǐng)求
502(Bad Gateway)
作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從上游服務(wù)器接收到無效的響應(yīng)
503(Service Unavailable)
表示服務(wù)器當(dāng)前很忙,暫時(shí)無法響應(yīng)服務(wù),我們上網(wǎng)時(shí)有時(shí)候遇到的“網(wǎng)絡(luò)服務(wù)正忙,請(qǐng)稍后重試”的提示信息就是狀態(tài)碼 503
容易爭(zhēng)論的點(diǎn)
301、302 和 307區(qū)別(對(duì) SEO 的影響)
301:可通知搜索引擎蜘蛛,表示某個(gè)網(wǎng)頁或網(wǎng)站已被永久移動(dòng)到新位置 302:搜索引擎蜘蛛會(huì)繼續(xù)抓取原有位置并將其編入索引,因此某個(gè)頁面或網(wǎng)站已被移動(dòng)時(shí),不要使用此代碼來通知搜索引擎蜘蛛。 307:臨時(shí)重定向,307 的定義實(shí)際上和 302 是一致的,唯一的區(qū)別在于,307 狀態(tài)碼不允許瀏覽器將原本為 POST 的請(qǐng)求重定向到 GET 請(qǐng)求上。
401 和 404 的區(qū)別
401 unauthorized,表示發(fā)送的請(qǐng)求需要有通過 HTTP 認(rèn)證的認(rèn)證信息 403 forbidden,表示對(duì)請(qǐng)求資源的訪問被服務(wù)器拒絕
打個(gè)生動(dòng)的比方:
401:我去找個(gè)人,門衛(wèi)說不認(rèn)識(shí)我不讓我進(jìn) 403:我去找個(gè)人,門衛(wèi)說認(rèn)識(shí)我,但是我不能進(jìn),因?yàn)槲也慌?/section>
你還有其他補(bǔ)充嗎?或?qū)ξ闹杏腥魏萎愖h,歡迎提交至 https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/500 ,你的每一次反饋對(duì)我們都至關(guān)重要,感謝
如果感覺還不錯(cuò),歡迎點(diǎn)贊與在看,你的點(diǎn)贊與在看都是對(duì)我們最好的支持??
最近開源了一個(gè)github倉(cāng)庫(kù):百問百答,在工作中很難做到對(duì)社群?jiǎn)栴}進(jìn)行立即解答,所以可以將問題提交至 https://github.com/Advanced-Frontend/Just-Now-QA ,我會(huì)在每晚花費(fèi) 1 個(gè)小時(shí)左右進(jìn)行處理,更多的是鼓勵(lì)與歡迎更多人一起參與探討與解答??
來自:https://github.com/Advanced-Frontend/Daily-Interview-Question
