关于ajax:CORS:当credentials标志为true时,无法在Access-Control-Allow-Origin中使用通配符

CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true

我有一个涉及

前端服务器(node.js,域:localhost:3000)<->后端(django,ajax,域:localhost:8000)

浏览器<--webapp<--node.js(为应用服务)

浏览器(webapp)->ajax->django(服务ajax post请求)

现在,我这里的问题是关于CORS设置,webapp使用它来对后端服务器进行Ajax调用。在铬合金中,我不断地

Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.

也不适用于火狐。

我的node.js安装程序是:

1
2
3
4
5
6
7
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请求如下:

1
2
3
4
5
6
7
8
9
10
11
$.ajax({
    type:"POST",
    url: 'http://localhost:8000/blah',
    data: {},
    xhrFields: {
        withCredentials: true
    },
    crossDomain: true,
    dataType: 'json',
    success: successHandler
});

因此,webapp发送的请求头如下所示:

1
2
3
4
5
6
7
8
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="***"

下面是响应头:

1
2
3
4
5
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 --disable-web-security,但现在我想让它实际工作。

编辑2:答案:

所以,我的解决方案django-cors-headers配置:

1
2
3
4
5
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/
)


这是安全的一部分,你不能这样做。如果您想允许凭证,那么您的Access-Control-Allow-Origin不能使用*。您必须指定确切的协议+域+端口。有关参考,请参阅以下问题:

  • 访问控制允许原始通配符子域、端口和协议
  • 使用凭据共享跨源资源
  • 除此之外,*过于放任,会破坏凭证的使用。因此,将http://localhost:3000http://localhost:8000设置为允许的原始头段。


    如果您使用的是CORS中间件,并且希望发送withCredentialboolean true,那么可以这样配置CORS:

    1
    2
    var cors = require('cors');    
    app.use(cors({credentials: true, origin: 'http://localhost:3000'}));


    如果您使用的是express,那么您可以使用cors包来允许这样的cors,而不是编写中间件;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var express = require('express')
    , cors = require('cors')
    , app = express();

    app.use(cors());

    app.get(function(req,res){
      res.send('hello');
    });


    试试看:

    1
    2
    3
    4
    5
    6
    7
    8
    const cors = require('cors')

    const corsOptions = {
        origin: 'http://localhost:4200',
        credentials: true,

    }
    app.use(cors(corsOptions));


    用于Chrome的开发,安装此加载项将消除该特定错误:

    1
    2
    3
    4
    5
    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模式添加到Intercepted URLs中。这里要添加的一个与http://localhost:8080一起使用的URL模式示例是:*://*