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"
    }
    
  • 相关阅读:
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第九章画线】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第八章色彩】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第七章数学函数】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第六章函数】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第五章数组】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第四章跳跃字和保留字】
    常用简体汉字
    mongodb json序列化时间格式
    awk 改名
    ssh 免密码登录linux
  • 原文地址:https://www.cnblogs.com/RandyField/p/13549318.html
Copyright © 2011-2022 走看看