MVC5 WebAPI 跨域 POST 请求失败

6 篇文章 0 订阅
3 篇文章 0 订阅

分享一个头疼了两天的问题哈!相信不少人都会遇到,我是在网上搜了很多解决方案都没能彻底解决;

我遇到的原因是因为 MVC4 升级到 MV5 后发现原先的 POST 接口居然不能跨域了;

试了很多方法,要么是 GET 请求正常了、POST 不正常,要么本地测试正常、发布到线上又异常了。

最终是得感谢这篇文章呐 ^ ^:https://blog.csdn.net/jacky_zh/article/details/72874889

在这里做个总结,希望能给大家提供些帮助吧!水平有限,请多多谅解~


1、跨域说明(以Chrome为参考)

  • 如 JS 发起 AJAX 请求的 URL ( IP / Port / Host ) 与当前网页 URL 不同的情况下,均视为跨域请求;
  • 由于浏览器的安全限制,默认不允许 JS 跨域请求;
  • 当在 JS 发起跨域请求时,浏览器会先将此 URL 以 OPTIONS 的形式向服务端发送 HTTP 请求进行验证;
  • 如服务端返回200状态、则告诉浏览器同意此跨域请求,此时浏览器才会真正的向服务端发送用户请求;

(因 此原因才会出现跨域的 POST 请求会被提交2次,不过第一次 OPTIONS 请求是不带 POST 参数的)

  • 如服务端返回非200状态时,浏览器就会拒绝此 JS 用户请求,会给 JS 返回一个 “net::ERR_FAILED” 状态、并触发 AJAX 的 error 回调;

2、服务端配置 > Web.config

PS:本地生产环境可以使用 * 号,但发布线上版本切记使用白名单做约束哦!

 <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--启用浏览器跨域调用(httpProtocol+handlers)-->
    <httpProtocol>
      <customHeaders>
        <!--定义允许跨域请求的域名(使用","逗号分隔,设为"*"则说明不限制)-->
        <add name="Access-Control-Allow-Origin" value="*" />
        <!--定义允许跨域请求的Http方法(使用","逗号分隔,设为"*"则说明不限制)-->
        <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
        <!--定义如请求头包含对应属性时就允许跨域(使用","逗号分隔,设为"*"则说明不限制)-->
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
      </customHeaders>
    </httpProtocol>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <!--<remove name="OPTIONSVerbHandler" /> #注释为解决OPTIONS无法验证问题-->
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

3、服务端配置 > Global.asax.cs

当以上配置后还无法使用的话、那就剩下这至关重要的一步啦!

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            //浏览器跨域 OPTIONS 验证
            if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
                Response.End(); //返回一个200状态表示允许此跨域请求
        }

好了,以上配置完后开始模拟一下接口调用吧!

4、服务端 > 创建测试接口

    public class TestController : ApiController
    {
        /// <summary>
        /// get 测试
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        [Route("~/test-get")]
        [HttpGet]
        public dynamic test_get(string a, string b)
        {
            return new { a = a, b = b };
        }

        /// <summary>
        /// post 测试
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        [Route("~/test-post")]
        [HttpPost]
        public dynamic test_post([FromBody] SortedList<string, string> json)
        {
            return json;
        }
    }

5、浏览器端 > 模拟跨域调用接口

<script>
    //Access to XMLHttpRequest at 'http://localhost:8112/test' from origin 'http://localhost:8115' 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.

    $(function () {
        $.ajax({
            url: "http://localhost:8112/test-get",
            type: "GET",
            data:
                {
                    a: 1,
                    b: 2
                },
            dataType: "json",
            success: function (json) {
                console.log(json);
                alert('Get调用成功:' + JSON.stringify(json));
            },
            error: function (request, status, errorThrown) {
                console.log(request);
                alert('Get调用失败:' + status);
            }
        });

        $.ajax({
            url: "http://localhost:8112/test-post",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify(
                {
                    a: 1,
                    b: 2
                }),
            dataType: "json",
            success: function (json) {
                console.log(json);
                alert('Post调用成功:' + JSON.stringify(json));
            },
            error: function (request, status, error) {
                console.log(request);
                alert('Post调用失败:' + status);
            }
        });
    });
</script>

6、好了,我这边测试成功啦!希望你们的也能成功!


只能帮到这了,祝大家生活愉快!笑口常开! !

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值