zoukankan      html  css  js  c++  java
  • 【Http】一文备忘Http状态码(406,415,422)

    最近在调试接口时,web api 报了一个415状态码。好久没见到这个状态码,一时还真不知道啥情况。所以,人的大脑是有遗忘规律的,为了加深印象,所以我觉得我有必要再复习一下。

    1.HTTP的状态码

    首先复习一下所有的状态码。

    • 1xx:属于信息性的状态码。Web API并不使用1xx的状态码。

    • 2xx:意味着请求执行的很成功。

      • 200:Ok,表示请求成功;
      • 201:Created,请求成功并创建了资源;
      • 204:No Content,请求成功,但是不应该返回任何东西,例如删除操作。
    • 3xx:用于跳转。例如告诉搜素引擎,某个页面的网址已经永久的改变了。绝大多数的Web API都不需要使用这类状态码。

    • 4xx:客户端错误

      • 400:Bad Request,表示API消费者发送到服务器的请求是有错误的;
      • 401:Unauthorized,表示没有提供授权信息或者提供的授权信息不正确;
      • 403:Forbidden,表示身份认证已经成功,但是已认证的用户却无法访问请求的资源;
      • 404:Not Found,表示请求的资源不存在;
      • 405:Method not allowed,当尝试发送请求到资源的时候,使用了不被支持的HTTP方法时,就会返回405状态码;
      • 406:Not acceptable,这表示API消费者请求的表述格式并不被Web API所支持,并且API不会提供默认的表述格式。例如请求的媒体类型是application/xml,但是Web API仅支持application/json类型,并且API不会将application/json作为默认格式提供;
      • 409:Conflict,表示请求与服务器当前状态冲突。通常指更新资源时发生的冲突,例如,当你编辑某个资源的时候,该资源在服务器上又进行了更新,所以你编辑的资源版本和服务器的不一致。当然有时候也用来表示你想要创建的资源在服务器上已经存在了。它就是用来处理并发问题的状态码。
      • 415:Unsupported media type,与406正好相反,有一些请求必须带着数据发往服务器,这些数据都属于特定的媒体类型,如果API不支持该媒体类型格式,415就会被返回。
      • 422:Unprocessable entity,它是HTTP扩展协议的一部分。它说明服务器已经懂得了实体的Content Type,也就是说415状态码肯定不合适;此外,实体的语法也没有问题,所以400也不合适。但是服务器仍然无法处理这个实体数据,这时就可以返回422。所以它通常是用来表示语意上有错误,通常就表示实体验证的错误。
    • 5xx:服务器错误

    • 500:Internal server error,表示服务器出现了错误,客户端无能为力,只能以后再试试了。

    ——摘自杨旭老师B站视频

    本篇重点关注状态码406和415,顺带看一下422。

    2.”我要的你不给“——406

    在http请求中,Accept表明客户端希望接收的数据类型。当请求包含accept头,在ASP.NET Core框架中,将会:

    • accept头中顺序枚举媒体类型
    • 尝试找到一个能生成accept中指定的格式之一的格式化器

    一旦找不到格式化器,ASP.NET Core将会:

    • 返回406 Not acceptable,只要需要设置如下:
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers(options =>
        {
            options.ReturnHttpNotAcceptable = true;
        })
    }
    
    • 或者尝试找到第一个可以生成响应的格式化程序:如果ASP.NET Core没有为所请求的格式配置格式化程序,则使用可以格式化该对象的第一个格式化程序.

    如果请求没有Accept头:

    • 使用第一个可以处理对象的格式化器来响应序列化
    • 不执行任何协商,由ASP.NET Core决定返回的格式

    Accept: */*,..,..,如果Accept 包含*/*,那么就会忽略Accept,除非做如下配置:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers(options =>
        {
            options.RespectBrowserAcceptHeader = true; // false by default
        });
    }
    

    这样,在使用 API 时,与在浏览器中的体验一致:

    • 忽略Accept
    • 若为另行配置,将会使用JSON返回内容

    3.“我给的你不要”——415

    说会我们问题的初衷,报了415,我这边ajax设置的Content-Type:application/x-www-form-urlencoded,然后asp.net core返回了415.

    在HTTP中,Content-Type代表客户端发送的实体数据的数据类型,如果客户端是以application/x-www-form-urlencoded ,在asp.net core中用[FromBody]接收,服务端api是不会接收数据,便会返回415 Unsupported Media Type-不支持的媒体类型。

    • application/x-www-form-urlencoded,使用[FromForm]接收数据
    • application/json,使用[FromBody]接收数据

    4.“我给的你还不要”——422

    顺带提一下并不常用,但是却非常有用的状态码——422。

    422:Unprocessable entity,它是HTTP扩展协议的一部分。

    • 服务器已经懂得了实体的Content Type的媒体类型,也就是说415状态码肯定不合适;
    • 此外,实体的语法也没有问题,所以400也不合适。

    但是服务器仍然无法处理这个实体数据,这时就可以返回422。所以它通常是用来表示语意上有错误,或者不符合接口要求的数据,通常就表示实体验证的错误。对于实体模型验证错误:

    ASP.NET Core默认使用的是400状态码-Bad Request

    {
      "errors": {
      },
      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
      "title": "One or more validation errors occurred.",
      "status": 400,
      "traceId": "|cb69a381-495c34b204e78961."
    }
    

    采用422会更准确的说明是实体数据问题。如果想要服务端返回422,还需要做单独配置,详细配置如下:

    services.AddControllers(options =>
    {
        options.ReturnHttpNotAcceptable = true;
    })
    .ConfigureApiBehaviorOptions(options =>
    {
        options.InvalidModelStateResponseFactory = context =>
        {
            var problemDetails = new ValidationProblemDetails(context.ModelState)
            {
                Type = "https://tools.ietf.org/html/rfc4918#section-11.2",
                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/rfc4918#section-11.2",
      "title": "One or more validation errors occurred.",
      "status": 422,
      "detail": "",
      "instance": "/api/admin/Sms",
      "traceId": "0HM25M2D86T30:00000001"
    }
    
  • 相关阅读:
    A1066 Root of AVL Tree (25 分)
    A1099 Build A Binary Search Tree (30 分)
    A1043 Is It a Binary Search Tree (25 分) ——PA, 24/25, 先记录思路
    A1079; A1090; A1004:一般树遍历
    A1053 Path of Equal Weight (30 分)
    A1086 Tree Traversals Again (25 分)
    A1020 Tree Traversals (25 分)
    A1091 Acute Stroke (30 分)
    A1103 Integer Factorization (30 分)
    A1032 Sharing (25 分)
  • 原文地址:https://www.cnblogs.com/RandyField/p/13549318.html
Copyright © 2011-2022 走看看