【问题标题】:CORS - jQuery get ajax response status failingCORS - jQuery 获取 ajax 响应状态失败
【发布时间】: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


【解决方案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

【讨论】:

    猜你喜欢
    • 2013-12-06
    • 2021-03-10
    • 2014-10-17
    • 2020-07-18
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    相关资源
    最近更新 更多