jQuery AJAX跨域调用不同Controller时Access Control校验失败求助
兄弟,你这问题太典型了——说白了就是浏览器的同源策略在搞事情。你看,你的前端页面是在http://nete-pelmer.com(HTTP协议),但AJAX请求的目标是https://nete-pelmer.com(HTTPS协议),这俩在浏览器眼里完全是不同的源,所以直接给你拦下来了。而请求同一Controller的时候,因为是同域同协议,自然就没这问题。
下面给你几个靠谱的解决办法,按优先级来:
1. 统一站点协议(最省心的方案)
先看看你的生产环境是不是已经全面启用HTTPS了?如果是,那直接把前端页面的访问地址都改成https://nete-pelmer.com就行。这样AJAX请求的源和目标协议一致,属于同源,CORS限制直接就不存在了,一劳永逸。
2. 后端添加CORS响应头
要是暂时没法统一协议,那就得在接收请求的那个Controller(也就是roadrace/support/sendMessage所在的后端)里配置CORS,允许来自http://nete-pelmer.com的请求。根据你用的后端框架,做法不一样:
比如你用的是ASP.NET MVC
可以给sendMessage方法加个特性,或者全局配置:
// 单方法配置 [EnableCors(origins: "http://nete-pelmer.com", headers: "*", methods: "*")] public ActionResult sendMessage(YourRequestModel model) { // 你的业务逻辑代码 return Json("发送成功", JsonRequestBehavior.AllowGet); } // 全局配置(在Global.asax.cs的Application_Start里) protected void Application_Start() { GlobalConfiguration.Configuration.EnableCors(new EnableCorsAttribute("http://nete-pelmer.com", "*", "*")); // 其他初始化代码 }
要是后端是PHP
就在sendMessage对应的PHP文件开头加上这些头:
header("Access-Control-Allow-Origin: http://nete-pelmer.com"); header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type");
3. 别忘了处理预检请求(OPTIONS)
浏览器发POST这类复杂请求之前,会先偷偷发一个OPTIONS请求探路,要是后端没正确响应这个请求,照样会报错。所以得确保后端能处理OPTIONS请求:
比如用Nginx反向代理的话,可以这么配置:
location /roadrace/support/sendMessage { if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin http://nete-pelmer.com; add_header Access-Control-Allow-Methods GET, POST, OPTIONS; add_header Access-Control-Allow-Headers Content-Type; return 204; # 空响应就行 } # 你的其他代理配置 }
4. 调试临时方案(别放生产!)
要是只是本地调试想快速验证,可以开Chrome的时候加个--disable-web-security参数,暂时关掉同源策略,但这只是权宜之计,生产环境绝对不能这么搞。
内容的提问来源于stack exchange,提问作者kofhearts

