使用 XMLHttpRequest 不断收到 No 'Access-Control-Allow-Origin' 错误
Posted
技术标签:
【中文标题】使用 XMLHttpRequest 不断收到 No \'Access-Control-Allow-Origin\' 错误【英文标题】:Keep getting No 'Access-Control-Allow-Origin' error with XMLHttpRequest使用 XMLHttpRequest 不断收到 No 'Access-Control-Allow-Origin' 错误 【发布时间】:2014-10-08 14:20:12 【问题描述】:我会通过使用 jQuery $.ajax
函数来解决这个问题,但在这种情况下,jQuery 不是选项。相反,我将使用 CORS 请求。我觉得响应请求的网络服务器有问题,我很难找出问题所在。
这是我创建 CORS 请求的代码
var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', url, true);
httpRequest.setRequestHeader( 'Access-Control-Allow-Origin', '*');
httpRequest.setRequestHeader( 'Content-Type', 'application/json' );
httpRequest.onerror = function(XMLHttpRequest, textStatus, errorThrown)
console.log( 'The data failed to load :(' );
console.log(JSON.stringify(XMLHttpRequest));
;
httpRequest.onload = function()
console.log('SUCCESS!');
这是 console.log 错误:
XMLHttpRequest 无法加载 http://test.testhost.com/testpage。请求头域 Access-Control-Allow-Origin 不允许 访问控制允许标头。
这是标题信息:
> Remote Address:**.**.***.**:80 Request
> URL:http://test.testdomain.com/testpage Request
> Request Method:OPTIONS
> Status Code:200 OK
请求标头:
OPTIONS /content-network HTTP/1.1
Host: test.testhost.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Access-Control-Request-Method: POST
Origin: http://test.testdomain.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Access-Control-Request-Headers: access-control-allow-origin, content-type
Accept: */*
Referer: http://test.testdomain.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
响应标头:
HTTP/1.1 200 OK
Date: Thu, 14 Aug 2014 20:17:25 GMT
Server: Apache
Last-Modified: Thu, 14 Aug 2014 20:17:25 +0000
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
ETag: "1408047445"
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Vary: Accept-Encoding
Content-Encoding: gzip
Access-Control-Allow-Headers: origin, x-requested-with, content-type
Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
Content-Length: 6117
Connection: close
Content-Type: text/html; charset=utf-8
【问题讨论】:
Access-Control-Allow-Origin
是在 服务器响应 中发送的标头,indicates that the client is allowed to see the contents of a result;它不是用于请求访问资源的请求标头。不要在您的请求中发送Access-Control-Allow-Origin
。
@apsillers 我已将 Header set Access-Control-Allow-Origin * 添加到 appache 中的 .htaccess、vhost 和 httpd.conf - 无济于事,并且启用了 apache 模块、标头、IS .
non-simple request headers here 的使用(Access-Control-Allow-Origin
不是简单的标头——也不应该由客户端发送——而application/json
是Content-Type
的非简单值) 浏览器正在发送a preflight OPTIONS request,以检查服务器是否通过Access-Control-Allow-Headers
允许这些请求标头。
@apsillers - 我已经用新的标题编辑了我的问题,我现在得到了 200 个响应,但是控制台中的 JS 出现了同样的错误。 ajax 和 XDomainRequest 不会发生此错误,但这不再是一个选项。
@apsillers - 再次编辑它们,如果以前没有,它们现在是正确的。
【参考方案1】:
我们在 OAuth2 集成中经常看到这一点。我们为客户提供 API 服务,他们会天真地尝试将他们的私钥放入 AJAX 调用中。 这确实是很差的安全性。编码良好的 API 网关、前端后端和其他此类代理不允许这样做。您应该收到此错误。
我将引用@aspillers 的评论并更改一个词:“Access-Control-Allow-Origin
是在服务器响应中发送的标头,表示允许客户端查看IF结果的内容”。
问题:问题在于开发人员试图将他们的私钥包含在客户端(浏览器)javascript 请求中。他们会得到一个错误,这是因为他们暴露了他们的客户秘密。
解决方案:让 JavaScript Web 应用程序与安全地保存客户端机密的后端服务通信。该后端服务可以向 OAuth2 提供者验证 Web 应用程序,并获取访问令牌。然后 Web 应用程序可以进行 AJAX 调用。
【讨论】:
【参考方案2】:在后端服务器上启用 CORS 要么 添加 chrome 扩展 https://chrome.google.com/webstore/search/CORS?utm_source=chrome-ntp-icon 并开启
【讨论】:
【参考方案3】:删除:
httpRequest.setRequestHeader( 'Access-Control-Allow-Origin', '*');
...并添加:
httpRequest.withCredentials = false;
【讨论】:
@SandeepanNath 用户询问的是http
,而不是https
。而false
是withCredentials
的默认设置。当false
时,跨站点访问控制请求是在不使用凭据(如 cookie、授权标头或 SSL 等 TLS 客户端证书)的情况下发出的,如本例所示。不明白的请不要投反对票。
好的,但我的评论在哪里?我再也看不到了【参考方案4】:
您的服务器的响应允许请求包含三个特定的non-simple headers:
Access-Control-Allow-Headers:origin, x-requested-with, content-type
但是您的请求包含服务器响应不允许的标头:
Access-Control-Request-Headers:access-control-allow-origin, content-type
在 CORS 请求中发送的所有非简单标头必须由 Access-Control-Allow-Headers
响应标头明确允许。服务器的 CORS 响应不允许在您的请求中发送不必要的 Access-Control-Allow-Origin
标头。这正是“...Access-Control-Allow-Headers
不允许”错误消息试图告诉您的内容。
请求没有理由有这个头:它什么都不做,因为Access-Control-Allow-Origin
是一个响应头,而不是一个请求头。
解决方案:删除在您的请求中添加Access-Control-Allow-Origin
标头的setRequestHeader
调用。
【讨论】:
【参考方案5】:除了您的 CORS 问题之外,您尝试访问的服务器还启用了 HTTP basic authentication。您可以通过在传递给 XHR 的 URL 中指定凭据来在跨域请求中包含凭据:
url = 'http://username:password@test.testhost.com/testpage'
【讨论】:
以上是关于使用 XMLHttpRequest 不断收到 No 'Access-Control-Allow-Origin' 错误的主要内容,如果未能解决你的问题,请参考以下文章
尝试将 Flask 应用程序部署到 AWS Elastic Beanstalk 时,我不断收到“ModuleNotFoundError: No module named 'app'”错误消息
获取downloadURL使用Firebase不断抛出错误'XMLHttpRequest未定义'
继续使用XMLHttpRequest获取No'Access-Control-Allow-Origin'错误