【发布时间】: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 就像一个魅力。
标签: php jquery ajax nginx cors