Ajax CORS:当凭据标志为true时,无法在访问控制允许原点中使用通配符
我有一个涉及 前端服务器(Node.js,域:localhost:3000)后端(Django,Ajax,域:localhost:8000) 浏览器Django(服务ajax POST请求) 现在,我的问题是CORS设置,webapp使用CORS设置对后端服务器进行Ajax调用。在chrome中,我一直 当凭据标志为true时,无法在访问控制允许原点中使用通配符 在firefox上也不起作用 我的Node.js设置是:Ajax CORS:当凭据标志为true时,无法在访问控制允许原点中使用通配符,ajax,django,node.js,cors,django-cors-headers,Ajax,Django,Node.js,Cors,Django Cors Headers,我有一个涉及 前端服务器(Node.js,域:localhost:3000)后端(Django,Ajax,域:localhost:8000) 浏览器Django(服务ajax POST请求) 现在,我的问题是CORS设置,webapp使用CORS设置对后端服务器进行Ajax调用。在chrome中,我一直 当凭据标志为true时,无法在访问控制允许原点中使用通配符 在firefox上也不起作用 我的Node.js设置是: var allowCrossDomain = function(req, r
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:8000/');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
};
在Django我用的是
webapp发出如下请求:
$.ajax({
type: "POST",
url: 'http://localhost:8000/blah',
data: {},
xhrFields: {
withCredentials: true
},
crossDomain: true,
dataType: 'json',
success: successHandler
});
因此,webapp发送的请求头如下所示:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE'
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: csrftoken=***; sessionid="***"
下面是响应标题:
Access-Control-Allow-Headers: Content-Type,*
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Content-Type: application/json
我哪里出错了
编辑1:我一直在使用chrome——禁用web安全性,但现在希望一切都能正常工作
编辑2:答案:
因此,我的解决方案django cors headers
config:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000' # Here was the problem indeed and it has to be http://localhost:3000, not http://localhost:3000/
)
如果您使用的是express
,那么您可以使用包来允许COR这样做,而不是编写中间件
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get(function(req,res){
res.send('hello');
});
这是安全的一部分,你不能这样做。如果要允许凭据,则您的访问控制允许源站
不得使用*
。您必须指定确切的协议+域+端口。有关参考信息,请参见以下问题:
此外,*
过于宽松,会妨碍凭证的使用。所以设置http://localhost:3000
或http://localhost:8000
作为允许来源标头。如果您正在使用CORS中间件,并且希望使用凭据发送
布尔值true,则可以如下配置CORS:
var cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:3000'}));
试试看:
const cors = require('cors')
const corsOptions = {
origin: 'http://localhost:4200',
credentials: true,
}
app.use(cors(corsOptions));
(编辑)以前推荐的加载项不再可用,您可以尝试
为了在Chrome中进行开发,请安装
将消除该特定错误:
Access to XMLHttpRequest at 'http://192.168.1.42:8080/sockjs-node/info?t=1546163388687'
from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the
'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'
when the request's credentials mode is 'include'. The credentials mode of requests
initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
安装后,通过单击加载项的(CORS,绿色或红色)图标并填写相应的文本框,确保将url模式添加到截获的url
。此处添加的示例URL模式将与http://localhost:8080
将是:*://*
如果您希望允许所有来源并保持凭据为真,这对我很有用:
app.use(cors({
origin: function(origin, callback){
return callback(null, true);
},
optionsSuccessStatus: 200,
credentials: true
}));
这对我在开发中很有效,但我不能建议在生产中,这只是完成工作的另一种方式,虽然还没有提到,但可能不是最好的方式。无论如何,这里有:
您可以从请求中获取来源,然后在响应头中使用它。以下是它在express中的外观:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.header('origin') );
next();
});
我不知道您的python设置会是什么样子,但这应该很容易翻译。在执行请求之前,angular遇到了这个问题,使用auth拦截器编辑标头。我们使用api令牌进行身份验证,所以我启用了凭据。现在,似乎不再需要/允许了
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = req.clone({
//withCredentials: true, //not needed anymore
setHeaders: {
'Content-Type' : 'application/json',
'API-TOKEN' : 'xxx'
},
});
return next.handle(req);
}
@Injectable()
导出类AuthInterceptor实现HttpInterceptor{
截取(req:HttpRequest,next:HttpHandler):可观察{
req=req.clone({
//withCredentials:true,//不再需要
集合标题:{
“内容类型”:“应用程序/json”,
“API-TOKEN”:“xxx”
},
});
返回next.handle(req);
}
除此之外,目前没有副作用。扩展@Renaud idea,cors现在提供了一种非常简单的方法:
从cors官方文件中发现:
"
原点:配置访问控制允许原点CORS标头。
可能值:
布尔值-将origin设置为true以反映请求来源,如req.header(“origin”)所定义,或将其设置为false以禁用CORS。
"
因此,我们只需执行以下操作:
const app = express();
const corsConfig = {
credentials: true,
origin: true,
};
app.use(cors(corsConfig));
最后,我认为值得一提的是,在一些用例中,我们希望允许来自任何人的跨源请求;例如,在构建公共RESTAPI时
注:
我本想把这作为对他的回答的一个评论,但不幸的是我没有信誉点。啊,现在这更方便了,但是,结果是一样的:(顺便说一句,我使用的是app.use(cors({credentials:true}))
您可能想查看经过测试的Django CORS中间件。那么您有两个Django中间件?我只会使用Django CORS header
应用程序。确保将localhost添加到CORS_ORIGIN_白名单
设置并将CORS_ALLOW_凭据
设置为True
是的,之前尝试过,但没有成功CORS\u ORIGIN\u ALLOW\u ALL=True
,CORS\u ORIGIN\u白名单=(“本地主机”)
和CORS\u ALLOW\u CREDENTIALS=True
我得到以下标题:Access Control ALLOW CREDENTIALS:True Access Control ALLOW Origin:http://localhost:3000/ 访问控制允许方法:POST、GET、OPTIONS、PUT、DELETE内容类型:application/json
阅读本文档后:i使用此配置:app.use(cors({credentials:true,origin:“}”);对我有效。但是如果有多个域怎么办?@aroth你可以给出一个域列表。相关问题:@user568109你能解释一下“除此之外,*
过于宽松,会妨碍凭据的使用。”?什么是“确切的域”如果请求来自移动设备,就像Cordova?@Christian有点老了,但是如果有人仍然好奇,这个问题只会发生在浏览器上运行的应用程序上,因为这个错误是由浏览器出于安全原因引发的。其他客户端,如移动应用程序、邮递员或任何其他使用http客户端的后端代码e一个请求不会有这个问题,所以你不必担心来源和确切的域。对我来说,它是没有http的localhost:3000,比如:CORS_origin_WHITELIST=('localhost:3000',)你的意思是在一台PC中开发前端和后端吗?不同PC中的前端和后端如何?@ixa