【发布时间】:2017-08-07 21:22:13
【问题描述】:
我很难让我的服务器接受来自另一台服务器的请求(本地,但在我的主机文件中给出了一个域名)而不触发可怕的
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-Origin 到 Request header field Authorization is not allowed by Access-Control-Allow-Headers.),但添加第二行只是将错误恢复为原始错误,我仍然被阻止。
此时,我不确定还可以尝试什么。
更新:
启动带有标志 --disable-web-security 的 Chrome 允许我进行测试,并且我的网站和代码在 Chrome 中运行良好。
但是,这揭示了另一个奇怪的问题,即如果我尝试将 add_header 行添加到位置指令,我的无网络安全 Chrome 和我未修改的 Safari 都无法从我的 api 加载信息。所以现在我不确定服务器块中的 add_header 指令是否正常工作。
如果有帮助,这是我的客户端代码(包括我尝试过/注释掉的内容):
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 不允许的原始错误,即使它们工作正常并且没有对服务器配置进行任何更改。今晚我会喝得酩酊大醉……
【问题讨论】:
-
您的 nginx 配置看起来正确。请更新您的问题,以在添加
add_header Access-Control-Allow-Headers Authorization行后包含您在浏览器开发工具控制台中看到的确切错误消息。 -
就像我上面说的,它只是恢复到原来的
Origin not allowed消息。 -
enable-cors.org/server_nginx.html 显示了 nginx 的完整 CORS 配置设置应该是什么样子。您可能想尝试尽可能地遵循这一点。不幸的是,您的问题中没有足够的细节能够知道,但是由于您的请求中存在 Authorization 标头,因此浏览器将对 OPTIONS 请求返回的响应中可能会发生一些问题。 (假设请求中有一个 Authorization 标头-无法确定,因为您的问题原样没有提供有关请求的详细信息……)
-
谢谢,但我试过了(甚至在标题列表中添加了授权),结果与上面完全相同,唉。
-
您应该删除
xhr.setRequestHeader('Access-Control-Allow-Origin','http://home.mydomain.org')。 Access-Control-Allow-Origin 严格来说是服务器发送的响应标头。从客户端将其作为请求标头发送的唯一影响是使 CORS 预检失败。同样的事情或注释掉的//xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true')。 Access-Control-Allow-Credentials 是严格的响应头,所以你绝对不想取消注释。
标签: wordpress nginx cors wordpress-rest-api