CORS - jQuery 获取 ajax 响应状态失败
Posted
技术标签:
【中文标题】CORS - jQuery 获取 ajax 响应状态失败【英文标题】:CORS - jQuery get ajax response status failing 【发布时间】:2018-10-15 20:26:33 【问题描述】:我遇到了对不同子域的 ajax 调用问题,请求从 www.mydomain.test 发送到 subdomain1.mydomain.test。我想处理 4xx 和 5xx 错误,以便重定向用户。
当从 FF 或 Chromium 执行时,当服务器返回 200 时调用完美运行,没有报告 CORS 问题,但是当服务器返回 4xx 时,jqXHR.status 属性设置为 0 并且我在控制台上收到以下 CORS 消息:
Failed to load http://subdomain1.mydomain.test/api.php: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.mydomain.test' is therefore not allowed access. The response had HTTP status code 418.
但是,使用 Postman 执行相同的调用总是会成功,即使服务器返回 418 或任何其他 4xx。
这是 JS 代码,从 www.mydomain.test 执行:
$.ajax(
url : "http://subdomain1.mydomain.test/api.php",
type : "POST",
success: function(response)
redirectToSucessPage();
,
error: function(jqXHR, textStatus, errorThrown)
console.log(textStatus); //prints out "error"
console.log(jqXHR.status); //prints out 0
if(jqXHR.status == 401) //never reached
redirectToErrorPage();
);
这是完整的控制台输出:
POST http://subdomain1.mydomain.test/api.php 418 ()
Failed to load http://subdomain1.mydomain.test/api.php: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.mydomain.test' is therefore not allowed access. The response had HTTP status code 418.
error
0
CORS 消息并没有完全困扰我,虽然我很困惑,因为它只发生在 4xx 响应中,但我真的需要响应的状态代码。服务器返回 418,但 jqXHR.status 为 0。
这是资源的 nginx 配置:
location = /api.php
root /path/to/dir;
add_header 'Access-Control-Allow-Origin' 'http://www.mydomain.test';
add_header 'Access-Control-Allow-Methods' 'POST';
limit_req zone=limitZoneOne burst=5;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
产生响应的 PHP 很简单:
http_response_code(418) and exit;
我在获取响应状态时是否犯了错误,或者是否存在一些我不知道的 4xx 响应的 CORS 问题?谢谢!
【问题讨论】:
还需要允许 OPTIONS 方法并在发送 POST 之前处理必须包含访问控制标头的预检 OPTIONS 请求。阅读 CORS 的工作原理 我之前曾尝试在 nginx 上允许 OPTIONS,但没有任何区别。对于问题可能是什么,或者代码/配置中缺少什么,您有什么具体建议吗? 您只需要在add_header
语句中指定always
参数即可。否则,只有在响应码为 200、201、204、206、301、302、303、304、307 或 308 时,nginx 才会添加 header。但如果指定 always
参数,则会添加 header 字段无论响应代码如何。见nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
@sideshowbarker 感谢您的提示,我刚刚尝试将 always 与 add_header 一起使用,但结果是一样的。不过,more_set_headers 就像一个魅力。
【参考方案1】:
通过在 nginx.conf 上使用 more_set_headers 而不是 add_header 解决:
location = /api.php
root /path/to/dir;
more_set_headers 'Access-Control-Allow-Origin:http://www.mydomain.test';
more_set_headers 'Access-Control-Allow-Methods: POST';
limit_req zone=limitZoneOne burst=5;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
即使没有 Access-Control-Allow-Methods 标头也可以在 FF 和 Chromium 上工作。
more_set_headers 指令是 HttpHeadersMore 模块的一部分,该模块包含在 nginx 的 nginx-extras flavor 中,您可以通过以下操作将其安装在 ubuntu 16 上:
sudo apt-get install nginx-extras
【讨论】:
以上是关于CORS - jQuery 获取 ajax 响应状态失败的主要内容,如果未能解决你的问题,请参考以下文章