Access-Control-Allow-Origin服务器mod无法正常工作

时间:2017-08-05 15:25:11

标签: wordpress nginx cors wordpress-rest-api

我正在努力让我的服务器接受来自其他服务器的请求(本地,但在我的hosts文件中给出一个域名)而不会触发可怕的

XMLHttpRequest cannot load https://dev.mydomain.org/api/user?uid=1. Origin http://home.domain.org is not allowed by Access-Control-Allow-Origin.

我的开发服务器(互联网)正在运行nginx,我的家庭服务器(本地)正在运行apache。

我尝试过在互联网上找到的几种解决方案,但无济于事。我已经尝试修改nginx配置中的头文件以允许我的home.mydomain.org服务器,我还在本地添加了htaccess规则以允许所有来源(*)。

我的nginx服务器块目前有这些行:

   add_header Access-Control-Allow-Origin http://home.mydomain.org; 
   add_header Access-Control-Allow-Headers Authorization;

只添加第一个确实稍微改变了我的回复(从简单的Origin not allowed by Access-Control-Allow-OriginRequest header field Authorization is not allowed by Access-Control-Allow-Headers.),但添加第二行只是将错误恢复为原始错误,我仍然被阻止。

此时,我不确定还有什么可以尝试。

更新

  1. 使用标记--disable-web-security启动Chrome可让我进行测试,我的网站和代码在Chrome中运行良好。

  2. 然而,这揭示了另一个奇怪的问题,即如果我尝试将add_header行添加到location指令,我的无网络安全Chrome和我未经修改的Safari都无法从我的api加载信息。所以现在我不确定服务器块中的add_header指令是否正常工作。

  3. 如果它有帮助,这里是我的客户代码(包括我尝试/注释掉的东西):

    var xhr = new XMLHttpRequest();
    var self = this;
    xhr.open('GET', apiURL + self.currentIssue);
    xhr.setRequestHeader('Access-Control-Allow-Origin','http://home.mydomain.org');
    //xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true');
    xhr.withCredentials = true;
    //xhr.setRequestHeader('Access-Control-Request-Method','*');
    xhr.setRequestHeader('Authorization','Bearer longstringoflettersandnumbers');
    xhr.onload = function () {
            self.posts = JSON.parse(xhr.responseText);
            };
    xhr.send();
    

    在尝试下面之后的另一个更新: 在客户端和服务器上进行了大量的试验和错误之后,我仍然陷入困境。这是我使用curl的服务器的最新响应(虽然我已经为各种选项客户端和服务器切换了一些内容,例如凭据和更改原点到我的确切或*无效):

    HTTP/1.1 204 No Content Server: nginx Date: Sun, 06 Aug 2017 10:11:57 GMT Connection: keep-alive Access-Control-Allow-Origin: http://home.mydomain.org Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range Access-Control-Max-Age: 1728000 Content-Type: text/plain; charset=utf-8 Content-Length: 0

    这是我的控制台错误(Safari):

    [Error] Origin http://home.mydomain.org is not allowed by Access-Control-Allow-Origin.
    [Error] Failed to load resource: Origin http://home.mydomain.org is not allowed by Access-Control-Allow-Origin. (actions, line 0)
    [Error] XMLHttpRequest cannot load https://dev.mydomain.org/api/user?uid=1 due to access control checks.
    

    这是Firefox的控制台错误:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://dev.mydomain.org/api/user?uid=1. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

    同样在Firefox中,以下是OPTIONS和GET网络面板的结果:

    Request URL: https://dev.mydomain.org/api/user?uid=1
    Request method: OPTIONS
    Status code: 204 No Content
    Version: HTTP/2.0
    
    Response headers (511 B)    
    Server  "nginx"
    Date    "Sun, 06 Aug 2017 10:44:22 GMT"
    Access-Control-Allow-Origin "http://home.mydomain.org"
    access-control-allow-credentials    "true"
    Access-Control-Allow-Methods    "GET, POST, OPTIONS"
    Access-Control-Allow-Headers    "Authorization,DNT,X-CustomHea…ent-Type,Content-Range,Range"
    Access-Control-Max-Age  "1728000"
    Content-Type    "text/plain; charset=utf-8"
    Content-Length  "0"
    X-Firefox-Spdy  "h2"
    Request headers (501 B) 
    Host    "dev.mydomain.org"
    User-Agent  "Mozilla/5.0 (Macintosh; Intel… Gecko/20100101 Firefox/54.0"
    Accept  "text/html,application/xhtml+x…lication/xml;q=0.9,*/*;q=0.8"
    Accept-Language "en-US,en;q=0.5"
    Accept-Encoding "gzip, deflate, br"
    Access-Control-Request-Method   "GET"
    Access-Control-Request-Headers  "authorization"
    Origin  "http://home.mydomain.org"
    Connection  "keep-alive"
    Cache-Control   "max-age=0"
    
    
    Request URL: https://dev.mydomain.org/api/user?uid=1
    Request method: GET
    Status code: 404 Not Found
    Version: HTTP/2.0
    
    Response headers (170 B)    
    Server  "nginx"
    Date    "Sun, 06 Aug 2017 10:44:22 GMT"
    Content-Type    "text/html"
    Vary    "Accept-Encoding"
    Content-Encoding    "gzip"
    X-Firefox-Spdy  "h2"
    Request headers (723 B) 
    Host    "dev.mydomain.org"
    User-Agent  "Mozilla/5.0 (Macintosh; Intel… Gecko/20100101 Firefox/54.0"
    Accept  "*/*"
    Accept-Language "en-US,en;q=0.5"
    Accept-Encoding "gzip, deflate, br"
    Referer "http://home.mydomain.org/"
    Authorization   "Bearer eyJ0eXAG…BRHmX9VmtYHQOvH7k-Y32wwyeCdk"
    Origin  "http://home.mydomain.org"
    Connection  "keep-alive"
    Cache-Control "max-age=0"
    

    部分成功更新:

    我认为我发现了问题(部分):将我在nginx中的位置指令从location /api更改为location = /api/*使其正常工作!但只有Safari和Chrome,FF现在甚至没有尝试GET请求,网络面板中没有条目。

    刷牙和牙齿的拉扯和头发拉伤的更新 Safari和Chrome间歇性地失败,原始错误关于Origin不允许,即使它们工作正常并且没有对服务器配置进行任何更改。今晚我会喝得很重......

1 个答案:

答案 0 :(得分:0)

哇,那令人费解。如果其他WP用户在这里找到他们的方式,请在此处发布答案。我不断得到不一致的结果(有时工作,有时不神秘),最后追踪我的问题到服务器上的PHP代码中设置的标题,独立于nginx设置,有时与它们相矛盾(尽管从来没有以可预测的方式我可以看到)。所以我需要解决的问题是:

  • 在我的nginx配置中删除了我所有的cors声明
  • 我的服务器上也有代码验证了auth头中的令牌,并且它在OPTIONS预检(它永远不应该检查)上失败了所以我不得不先添加一个if语句让它忽略一个OPTIONS调用( !$_SERVER['REQUEST_METHOD'] === "OPTIONS"
  • 由于我使用UpdraftPlus插件从我的另一个网站克隆了这个网站,我不得不进入删除我的迁移密钥,因为它们的存在阻止了api调用。删除后,我的电话又开始工作了。
  • 删除并重新添加内置WP过滤器rest_pre_serve_request

我的过滤器代码在这里:

add_action('rest_api_init', function() {
/* unhook default function */
remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');   
/* then add your own filter */
add_filter('rest_pre_serve_request', function( $value ) {
$origin = get_http_origin();
$my_sites = array( $origin ); // add array of accepted sites if you prefer
if ( in_array( $origin, $my_sites ) ) {
header( 'Access-Control-Allow-Origin: ' . esc_url_raw( $origin ) );
} else {
header( 'Access-Control-Allow-Origin: ' . esc_url_raw( site_url() ) );
}
header( 'Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE' );
header( 'Access-Control-Allow-Credentials: true' );
header('Access-Control-Allow-Headers: Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Origin,Content-Type,X-Auth-Token,Content-Range,Range');
header('Access-Control-Expose-Headers: Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Origin,Content-Type,X-Auth-Token,Content-Range,Range');
header( 'Vary: Origin' );
return $value;
});
}, 15);

现在终于,一切都在无处不在(在每个浏览器和卷曲中)!