跨域jQuery AJAX GET请求所需响应头及API配置咨询
让我一步步帮你拆解这个问题,理清跨域请求的核心逻辑和解决方案:
问题根源分析
你的AJAX请求触发了CORS预检请求(OPTIONS)——因为你在请求里设置了自定义的Accept头(application/json; odata=verbose),同时指定了contentType:"application/json; charset=utf-8",这些都属于非简单请求的范畴。浏览器会先发送OPTIONS请求到API服务器,确认是否允许这个跨域请求。
原来的API只返回了Access-Control-Allow-Origin: *,没有处理OPTIONS请求,也没有返回预检所需的关键响应头,所以浏览器直接拒绝了后续的GET请求,导致NetworkError。而CORS扩展自动补充了这些缺失的响应头,所以请求能正常执行。
你提到的响应头是否必需?
Access-Control-Allow-Origin: *:必需,这是CORS的核心头,用于允许指定域名的跨域请求(如果需要限制到你的Web应用,也可以把*换成http://app.mydomain.tld)。Access-Control-Allow-Methods:对于预检请求是必需的,它告诉浏览器API允许哪些HTTP方法。你的请求用了GET,但如果API支持其他方法,或者需要通过预检确认允许的方法,这个头是必要的。Access-Control-Allow-Headers:这里你写错了内容!你当前写的access-control-allow-methods,access-control-allow-origin是响应头的名称,而不是请求中实际携带的头。这个头需要列出你的AJAX请求中使用的自定义请求头——也就是你设置的Accept,以及Content-Type。
你的PHP代码调整建议
你的思路方向是对的,但Access-Control-Allow-Headers的内容需要修正,同时要确保API能正确处理OPTIONS预检请求。调整后的代码如下:
<?php // 优先处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS"); // 允许请求中实际携带的自定义头 header("Access-Control-Allow-Headers: Accept, Content-Type"); // 预检请求无需返回内容,直接结束 exit(); } // 处理正常请求的CORS头 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS"); header("Access-Control-Allow-Headers: Accept, Content-Type"); // 你的API业务逻辑代码... ?>
这样就能正确响应预检请求,允许你的AJAX请求中的自定义头,彻底解决跨域问题。
无需修改API代码的解决方案
如果无法修改API代码,有两个可行方案(除了JSONP):
- 开发阶段使用CORS扩展:就是你现在用的Chrome扩展,但这仅适用于本地开发,普通用户的浏览器不会安装,不适合生产环境。
- 反向代理(生产环境推荐):在你的Web应用服务器(
http://app.mydomain.tld)上配置反向代理,把API请求转发到https://api.mydomain.tld。比如用Nginx的话,可以添加类似这样的配置:
之后你的AJAX请求URL改成location /api/ { proxy_pass https://api.mydomain.tld/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }/api/GetSomething/read.php(和Web应用同域),服务器会自动转发到真实的API地址,这样就不存在跨域问题了。
内容的提问来源于stack exchange,提问作者Pepozzo
相关产品推荐
相关产品推荐

