问题:
每当我向子域发出AJAX请求时,我都会收到错误。
错误告诉我请求的资源上没有“Access-Control-Allow-Origin”标题。
然而,我似乎在需要的地方指定了“Access-Control-Allow-Origin”?
我犯了什么错误,如何解决这个问题?
错误:
无法加载https://subdomain.example.com/endpoint
:对预检请求的响应未通过访问控制检查:请求的资源上没有“Access-Control-Allow-Origin”标头。因此,不允许来源“https://www.example.com
”。响应的HTTP状态代码为500。
CODE:
客户端
$.ajax({
type: "POST",
url: "https://subdomain.example.com/endpoint",
data: theData,
headers: {
'Access-Control-Allow-Origin': 'https://example.com',
'Access-Control-Allow-Credentials': true
},
timeout: 600000,
async: true,
xhrFields: {withCredentials: true},
crossDomain: true
}).done(function(response) {
服务器
var whitelist = ['https://example.com'];
var corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
credentials: true
}
router.options('/', cors(corsOptions), function(req,res,next){
res.setHeader('Access-Control-Allow-Origin', 'https://example.com');
res.status(200).end();
});
router.post("/", cors(corsOptions), function(req, res, next){
res.setHeader('Access-Control-Allow-Origin', 'https://example.com');
res.setHeader('Access-Control-Allow-Credentials', true);
...etc...
答案 0 :(得分:0)
自从我使用node以来已经很长时间了,但只是查看代码,我认为您需要删除客户端请求中的标头。
然后确保在服务器响应中添加这些内容:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
检查节点中的cors包是否已经执行此操作。
您在/< - 端点上发送标头,但在客户端中调用/ endpoint。最后一条路径可能没有设置任何访问控制头文件头。
要调试: 检查您的开发者控制台 - >网络,以查看正在访问的URL以及响应标头的内容。你应该看到这些访问控制标题。
如果您在那里看不到它们,则表示您的服务器端无法正常工作。
并且确定一下:确保您从https://github.com/expressjs/cors调用API,因为https://example.com将
答案 1 :(得分:0)
您可能错过了
Vary
标头。检查我的Vary标题部分。
的说明强>
在客户端 - 服务器体系结构中,Access-Control-Allow-Origin
是服务器端标头,通过它可以告诉浏览器是否允许它访问服务器上的资源。
Read this excellent mozilla documentation
在现代浏览器中,即使在客户端向服务器发出请求之前,浏览器也会发出预请求(a.k.a飞行前请求)以检查是否允许客户端向服务器发出请求。服务器应使用适当的标头响应浏览器以获取飞行前请求。作为响应,服务器必须发送Access-Control-Allow-Origin
标头。如果您的主机名在服务器响应中返回,浏览器将允许您进行该呼叫,否则将阻止该呼叫。
很常见的情况是,服务器回复*
作为Access-Control-Allow-Origin
的值来指示浏览器每个人都可以拨打电话,但显然这不是一个好习惯,直到您打算制作服务器向公众开放。
Vary标题
根据文件,
如果服务器指定了源主机而不是" *",那么它还必须在Vary响应头中包含Origin,以向客户端指示服务器响应将根据Origin请求的值而不同报头中。
Access-Control-Allow-Origin: https://developer.mozilla.org
Vary: Origin
备注强>
此字段只能包含*
或特定值。您不能使用逗号分隔值来允许多个主机。如果您想要允许多个主机(例如localhost用于本地测试,example.com用于生产),那么您可以轻松地在服务器端编写一些逻辑,如下所示:
let list = ['example.com', 'localhost']
if (request.headers.origin in list) {
response.headers['Access-Control-Allow-Origin'] = request.headers.origin
}
以上PSEUDO-CODE
基本上检查您的请求者是否在您允许的主机列表中,然后将该主机作为响应发送。