XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制

Posted

技术标签:

【中文标题】XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制【英文标题】:The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute 【发布时间】:2018-05-24 21:07:23 【问题描述】:

在我问这个问题之前,我已经阅读了这个related post。

在我的 settings.py 中:

INSTALLED_APPS = [
    ...
    'corsheaders',
]

CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
        'http://103.200.30.76'
        )

我的网站前端使用 Apache 监听 80 端口,我使用

python3 manage.py runserver 103.200.30.76:8001

但我仍然收到以下错误:

无法加载http://103.200.30.76:8001/api/website/websitemanage/footerreconmend/list/:对预检请求的响应未通过访问控制检查:响应中的“Access-Control-Allow-Origin”标头的值不能是通配符“*”,当请求的凭据模式是“包含”。因此,Origin 'http://103.200.30.76' 不允许访问。 。

其中一个请求是这样的:

General:

Request URL:http://103.200.30.76:8001/api/website/websitemanage/homepagefunctionshow/list/
Request Method:OPTIONS
Status Code:200 OK
Remote Address:103.200.30.76:8001
Referrer Policy:no-referrer-when-downgrade

Response Headers

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with
Access-Control-Allow-Methods:DELETE, GET, OPTIONS, PATCH, POST, PUT
Access-Control-Allow-Origin:http://103.200.30.76
Access-Control-Max-Age:86400
Content-Length:0
Content-Type:text/html; charset=utf-8
Date:Mon, 11 Dec 2017 02:44:12 GMT
Server:WSGIServer/0.2 CPython/3.5.2
Vary:Origin
X-Frame-Options:SAMEORIGIN

Request Headers:

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.9,en;q=0.8
Access-Control-Request-Headers:access-control-allow-origin,x-requested-with
Access-Control-Request-Method:GET
Connection:keep-alive
Host:103.200.30.76:8001
Origin:http://103.200.30.76
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36

那么,谁能帮帮我呢?


编辑

我发现,如果我使用下面的命令(disable-web-security)打开 Chrome,我不会有这个问题。

open -a "Google Chrome" --args --disable-web-security --user-data-dir


编辑 - 2

我尝试了 Naqib Hakimi 的回答,使用中间件:

class AccessControl(MiddlewareMixin):
    def process_request(self, request):

        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = http.HttpResponse()
            response["Access-Control-Allow-Origin"]= "*"
            response["Access-Control-Allow-Credentials"] = "true"
            response["Access-Control-Allow-Methods"]= "GET,HEAD,OPTIONS,POST,PUT"
            response["Access-Control-Allow-Headers"] = "Authentication , Authorization , X-CSRF-Token , Access-Control-Allow-Credentials , Access-Control-Allow-Methods , Access-Control-Allow-Origin , Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"

            return response

        return None

但还是有这个问题。

我在调试器中检查了请求:

request.META 中没有HTTP_ACCESS_CONTROL_REQUEST_METHOD

【问题讨论】:

【参考方案1】:

默认情况下,django 不允许所有域使用 Access-Control-Allow-Origin,您应该添加 MIDDLEWARE_CLASSES 来执行此操作。

class AccessControl(object):
    def process_request(self, request):

        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = http.HttpResponse()
            response["Access-Control-Allow-Origin"]= "*"
            response["Access-Control-Allow-Credentials"] = "true"
            response["Access-Control-Allow-Methods"]= "GET,HEAD,OPTIONS,POST,PUT"
            response["Access-Control-Allow-Headers"] = "Authentication , Authorization , X-CSRF-Token , Access-Control-Allow-Credentials , Access-Control-Allow-Methods , Access-Control-Allow-Origin , Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"

            return response

        return None

然后在setting.py中

MIDDLEWARE_CLASSES = [
    ...
    'app.filename.AccessControl',

    ]

这将允许来自所有域的请求

【讨论】:

以上是关于XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制的主要内容,如果未能解决你的问题,请参考以下文章

XMLHttpRequest + JSON + 文件上传 + axios

ajax基础3--使用原生xhr发起get,post请求

跨域问题

控制台实现js发起http请求 —— AJAX 实例解析

跨域CORS

使用axios发起get请求和post请求