使用django-cors-headers解決Django和vue跨域问题

使用django-cors-headers解決Django和vue跨域问题

问题一:前端使用vue,后端使用django,采用前後端分离的开发方式。前後端部署在不同的服务器上,其中前端部署在nginx上,后端部署在apache上。跨域问题解决步骤如下:

1.安装django-cors-headers

 pip install django-cors-headers

2.配置settings.py文件

# 导入app
INSTALLED_APPS = [
	...
	'corsheaders',	
	...
]	

# 增加中间件
MIDDLEWARE = [
	...
    'corsheaders.middleware.CorsMiddleware',  # 注意顺序,必须放在这儿
    'django.middleware.common.CommonMiddleware',
    ...
]

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
# 允许所有方法
CORS_ALLOW_METHODS = ('*')
# 允许所有请求头
CORS_ALLOW_HEADERS = ('*')

一般情况到这一步就解决了跨域问题。可是我遇到一个奇葩问题。

问题二:系统测试过程中谷歌浏览器可以正常登陆访问,但IE登陆过程中显示Network Error,后来发现在一些低版本的谷歌浏览器上也出现相同的问题。调试过程中发现正常情况下后台接收到的请求是GET,发生异常时后端接收到的请求是OPTIONS。通过F12查看报错信息:要求標頭 token 不存在於 Access-Control-Allow-Headers 清單中。查询资料得知仍然是跨域问题,具体原因如下:

原因: XHR对象对于HTTP跨域请求有三种:简单请求、Preflighted请求、Preflighted认证请求。简单请求不需要发送OPTIONS嗅探请求,但只能发送简单的GET、HEAD或POST请求,且不能自定义HTTP Headers。Preflighted请求和认证请求,XHR会首先发送一个OPTIONS嗅探请求,然后XHR会根据OPTIONS请求返回的Access-Control-*等头信息判断是否有对指定站点的访问权限,并最终决定是否发送实际请求信息。我发送的是GET请求,但自定义了header信息(将userid和token存储在header中用于验证登录是否有效),所以访问过程中浏览器会去向Server端发送一个OPTIONS请求,看Server返回的"Access-Control-Allow-Headers"是否有自定义的header字段。因为我之前没有返回自定义的字段,所以,默认是不允许的,造成了客户端没办法拿到数据。解决办法在settings.py中添加如下语句:

# IE跨域問題。报错:要求標頭 token 不存在於 Access-Control-Allow-Headers 清單中
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = default_headers + (
    'token',
    'userid'
)

你可能感兴趣的:(django,跨域,django,vue,nginx,IE)