• Webapi处理跨域请求,你可能踩到的坑


     本文基于最近在搭的Vue+Framwork4.8项目,在处理跨域时,和.Net5+有所差异,特此记录:

    问题1:
    报错:Access to XMLHttpRequest at 'https://localhost:44391/api/Hold/GetLotInfoList' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    原因:

    在跨域访问web api的api时,C#自带的web api并不能支持跨域访问,如果需要,可以更改配置来实现

    解决办法:

    (1)允许所有来源,HTTP方法,请求标头跨域:
      后端,在Web.config中找到<system.webServer>标签,里面添加配置如下:

    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*"/>
        <add name="Access-Control-Allow-Headers" value="*" />
        <!--<add name="Access-Control-Allow-Headers" value="Content-Type,Token" />-->
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>

    附上文件截图

    (2)指定对应来源,HTTP方法和请求标头跨域:

      详情参考微软官方文档:链接

    问题2:

    修改上述问题后,某些请求还是会报错:has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status

    原因:

    带有[FormQuery](4.8中称为[FormUri])参数或无参的请求调用正常,带有[FormBody]即json参数的请求会报上述错误。

    这里是与预检(options)请求的问题。

    后台方法允许OPTIONS请求,但是一些配置文件(如安全配置)阻止了OPTIONS请求,就会导致上述错误

     解决办法:

    需要在后端加上预检请求过滤——只要是预检请求,都返回success,再正常接收后续请求

    后端,在Global.asax文件添加配置如下:

    /// <summary>
            /// 跨域设置(响应预检Options请求)
            /// </summary>
            protected void Application_BeginRequest()
            {
                //OPTIONS请求方法的主要作用(预请求,判断是否能够请求成功):
                //用来检查服务器的性能。如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
                if (Request.Headers.AllKeys.Contains("origin") && Request.HttpMethod == "OPTIONS")
                {
                    //表示对输出的内容进行缓冲,执行page.Response.Flush()时,会等所有内容缓冲完毕,将内容发送到客户端。
                    //这样就不会出错,造成页面卡死状态,让用户无限制的等下去
                    //Response.StatusCode = 204;
                    Response.Flush();
                }
            }

    附上文件截图

     

    ps:关于预检Options请求

    浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

    1、简单请求

    同时满足以下两个条件的属于简单请求:

    (1)HEAD、GET、POST请求

    (2)HTTP的头信息不超出以下几种字段:

    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

    浏览器会直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

    2、非简单请求

     对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。

     非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

    浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

    预请求实际上是对服务端的一种权限请求。请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。

     

    参考:

    个人认为最实用的一版!!

    No 'Access-Control-Allow-Origin' header is present on the requested resource——Web Api跨域问题

    预检请求:

    ajax跨域,这应该是最全的解决方案了

    http CORS options请求(预检请求)详解

    CORS预检请求详谈

    后端关闭对应的安全配置
  • 相关阅读:
    虚拟机磁盘和OSNetworkManagement
    虚拟化的设计考量
    魔獸世界台服身份證ID生成器
    完美的Windows Server 2008 R2 SP1 模板
    Windows 脚本主机概述
    创建动态链接库的方法简介
    iPad3越狱方法
    关于用netsh.exe配置系统防火及网络
    金蝶客户端多用户远程桌面解决方案
    poj 1459 最大流(EK实现)
  • 原文地址:https://www.cnblogs.com/Yan3399/p/16443497.html
Copyright © 2020-2023  润新知