当前位置: 代码迷 >> 综合 >> MVC5 WebAPI 跨域 POST 请求失败
  详细解决方案

MVC5 WebAPI 跨域 POST 请求失败

热度:55   发布时间:2023-12-10 17:49:58.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、好了,我这边测试成功啦!希望你们的也能成功!


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

  相关解决方案