【Http】一文备忘Http状态码(406,415,422)
最近在調(diào)試接口時,web api 報了一個415狀態(tài)碼。好久沒見到這個狀態(tài)碼,一時還真不知道啥情況。所以,人的大腦是有遺忘規(guī)律的,為了加深印象,所以我覺得我有必要再復習一下。
1.HTTP的狀態(tài)碼
首先復習一下所有的狀態(tài)碼。
- 1xx:屬于信息性的狀態(tài)碼。Web API并不使用1xx的狀態(tài)碼。 
- 2xx:意味著請求執(zhí)行的很成功。 
- 3xx:用于跳轉(zhuǎn)。例如告訴搜素引擎,某個頁面的網(wǎng)址已經(jīng)永久的改變了。絕大多數(shù)的Web API都不需要使用這類狀態(tài)碼。 
- 4xx:客戶端錯誤 
- 406:Not acceptable,這表示API消費者請求的表述格式并不被Web API所支持,并且API不會提供默認的表述格式。例如請求的媒體類型是application/xml,但是Web API僅支持application/json類型,并且API不會將application/json作為默認格式提供; 
- 409:Conflict,表示請求與服務器當前狀態(tài)沖突。通常指更新資源時發(fā)生的沖突,例如,當你編輯某個資源的時候,該資源在服務器上又進行了更新,所以你編輯的資源版本和服務器的不一致。當然有時候也用來表示你想要創(chuàng)建的資源在服務器上已經(jīng)存在了。它就是用來處理并發(fā)問題的狀態(tài)碼。 
- 415:Unsupported media type,與406正好相反,有一些請求必須帶著數(shù)據(jù)發(fā)往服務器,這些數(shù)據(jù)都屬于特定的媒體類型,如果API不支持該媒體類型格式,415就會被返回。 
- 422:Unprocessable entity,它是HTTP擴展協(xié)議的一部分。它說明服務器已經(jīng)懂得了實體的Content Type,也就是說415狀態(tài)碼肯定不合適;此外,實體的語法也沒有問題,所以400也不合適。但是服務器仍然無法處理這個實體數(shù)據(jù),這時就可以返回422。所以它通常是用來表示語意上有錯誤,通常就表示實體驗證的錯誤。 
 
- 5xx:服務器錯誤 
——摘自楊旭老師B站視頻。
本篇重點關注狀態(tài)碼406和415,順帶看一下422。我們就類比愛情,對客戶端與服務端交互的狀態(tài)碼進行解釋。
2.Server:”你要的我給不了“——406
在http請求中,會在Accept表明客戶端希望接收的數(shù)據(jù)類型。當請求包含*accept頭,在ASP.NET Core*框架中,將會:
- 按*accept*頭中的順序枚舉媒體類型 
- 嘗試找到一個能生成*accept*中指定的格式之一的格式化器 
找到了,就還罷了,一旦找不到格式化器,ASP.NET Core將會:
- 返回406 Not acceptable,只要需要設置如下: 
2.1 其他策略
- 嘗試找到第一個可以生成響應的格式化程序:如果ASP.NET Core沒有為所請求的格式配置格式化程序,則使用可以格式化該對象的第一個格式化程序. 
如果請求沒有Accept頭:
- 使用第一個可以處理對象的格式化器來響應序列化 
- 不執(zhí)行任何協(xié)商,由ASP.NET Core決定返回的格式 
Accept: */*,..,..,如果Accept 包含*/*,那么就會忽略Accept,除非做如下配置:
public?void?ConfigureServices(IServiceCollection?services) {services.AddControllers(options?=>{options.RespectBrowserAcceptHeader?=?true;?//?false?by?default}); }這樣,在使用 API 時,與在瀏覽器中的體驗一致:
- 忽略Accept 
- 若為另行配置,將會使用JSON返回內(nèi)容 
3.Server:“你給的我不要”——415
說回我們問題的初衷,報了415,我這邊ajax設置的Content-Type:application/x-www-form-urlencoded,然后asp.net core返回了415.
在HTTP中,Content-Type代表客戶端發(fā)送的實體數(shù)據(jù)的數(shù)據(jù)類型,如果客戶端是以*application/x-www-form-urlencoded*** ,在asp.net core中用***[FromBody]*接收,服務端api是不會接收數(shù)據(jù),便會返回415 Unsupported Media Type-不支持的媒體類型。
- application/x-www-form-urlencoded,使用***[FromForm]***接收數(shù)據(jù) 
- application/json,使用***[FromBody]***接收數(shù)據(jù) 
4.Server:“你給的,不是我想要的”——422
順帶提一下并不常用,但是卻非常有用的狀態(tài)碼——422。
422:Unprocessable entity,它是HTTP擴展協(xié)議的一部分。
- 服務器已經(jīng)懂得了實體的Content Type的媒體類型,也就是說415狀態(tài)碼肯定不合適; 
- 此外,實體的語法也沒有問題,所以400也不合適。 
但是服務器仍然無法處理這個實體數(shù)據(jù),這時就可以返回422。所以它通常是用來表示語意上有錯誤,或者不符合接口要求的數(shù)據(jù),通常就表示實體驗證的錯誤。對于實體模型驗證錯誤:
*ASP.NET Core*默認使用的是400狀態(tài)碼-Bad Request
{"errors":?{},"type":?"https://tools.ietf.org/html/rfc7231#p-6.5.1","title":?"One?or?more?validation?errors?occurred.","status":?400,"traceId":?"|cb69a381-495c34b204e78961." }更換采用422會更準確的說明是實體數(shù)據(jù)問題。如果想要服務端返回422,還需要做單獨配置,詳細配置如下:
services.AddControllers(options?=> {options.ReturnHttpNotAcceptable?=?true; }) .ConfigureApiBehaviorOptions(options?=> {options.InvalidModelStateResponseFactory?=?context?=>{var?problemDetails?=?new?ValidationProblemDetails(context.ModelState){Type?=?"https://tools.ietf.org/html/rfc7231#p-6.5.1",Title?=?"One?or?more?validation?errors?occurred.",Status?=?StatusCodes.Status422UnprocessableEntity,Detail?=?"",Instance?=?context.HttpContext.Request.Path};problemDetails.Extensions.Add("traceId",?context.HttpContext.TraceIdentifier);return?new?UnprocessableEntityObjectResult(problemDetails){ContentTypes?=?{?"application/problem+json"?}};}; }); {"errors": {},"type": "https://tools.ietf.org/html/rfc7231#p-6.5.1","title": "One or more validation errors occurred.","status": 422,"detail": "","instance": "/api/admin/Sms","traceId": "0HM25M2D86T30:00000001" } 長按二維碼關注點外賣,先領券總結(jié)
以上是生活随笔為你收集整理的【Http】一文备忘Http状态码(406,415,422)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 盘点大厂的那些开源项目 - 华为
- 下一篇: WebRTC成为W3C和IETF正式标准
