一、问题背景

  之前使用django+vue进行前后端分离碰到跨域请求问题,跨域(域名或者端口不同)请求问题的本质是由于浏览器的同源策略导致的,当请求的响应不是处于同一个域名和端口下,浏览器不会接受响应,同源策略也是浏览器针对请求的安全问题所作出的一种保护行为。针对跨域问题,可以有下面的解决方式:

  • JSONP方式
  • 自定义中间件,设置响应头
  • 使用django-cors-headers包

二、解决方式

(一)自定义中间件

  JSONP本质上是利用html的一些不受同源策略影响的标签属性src,例如:<a>、<img>、<script>等标签的src属性,从而实现跨域请求,但是这种方法只支持GET的请求方式,这里暂不做过多讨论,主要说自定义中间件以及利用django-cors-headers包来实现跨域。

1、自定义中间件

class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__() def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response class CORSMiddleware(MiddlewareMixin): def process_response(self,request,response):
# 添加响应头
# 允许相应的域名来访问,多个域名中间以逗号隔开,如果全部可使用'*'
response['Access-Control-Allow-Origin'] = "*"
# 允许携带的请求头,多个中间以逗号隔开
response['Access-Control-Allow-Headers'] = "Content-Type"
# 允许发送的请求方式
response['Access-Control-Allow-Methods'] = "DELETE,PUT"
return response

2、注册中间件(在settings文件中注册)

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
...
...
'crm.utils.cors.CORSMiddleware' #跨域中间件
]

(二)CORS(Cross-Origin Resource Sharing)

1、安装django-cors-headers包

pip install django-cors-headers #在对应的开发环境中安装

2、修改settings文件

  • 注册应用
# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
...'django.contrib.staticfiles',
'corsheaders',#放在新建应用之前
'rest_framework',
...'crm'
]
  • 中间件注册
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # 注意顺序,放在此处
'django.middleware.common.CommonMiddleware',
...
]
  • 其它设置
CORS_ORIGIN_ALLOW_ALL = True  #允许所有的请求,或者设置CORS_ORIGIN_WHITELIST,二选一
CORS_ALLOW_HEADERS = ('*') #允许所有的请求头
CORS_ALLOW_CREDENTIALS = True # 允许携带cookie,前端需要携带cookies访问后端时,需要设置withCredentials: true

这样就可以进行跨域使用了。

  但是大多数站点将需要利用Django提供的跨站点请求伪造保护。CORS和CSRF是分开的,并且Django无法使用您的CORS配置免除网站Referer对安全请求所做的检查。做到这一点的方法是使用其CSRF_TRUSTED_ORIGINS设置。

3、CSRF整合

#1、CSRF_TRUSTED_ORIGINS  设置
CORS_ORIGIN_WHITELIST = [
' http://read.only.com ',
' http://change.allowed.com ',
] #不需要CORS_ORIGIN_ALLOW_ALL=True的设置 CSRF_TRUSTED_ORIGINS = [
' change.allowed.com ',
] #2、中间件设置
#启用此功能在django.middleware.csrf.CsrfViewMiddleware后,还应添加#corsheaders.middleware.CorsPostCsrfMiddleware
MIDDLEWARE_CLASSES = [
...
' corsheaders.middleware.CorsMiddleware ',
...
' django.middleware.csrf.CsrfViewMiddleware ',
'corsheaders.middleware.CorsPostCsrfMiddleware ',
...
]

详情参考官方文档https://github.com/adamchainz/django-cors-headers

Django前后端分离跨域请求问题的更多相关文章

  1. 关于.Net Core 前后端分离跨域请求时 ajax并发请求导致部分无法通过验证解决办法。

    项目中有这样一个页面.页面加载的时候会同时并发6个ajax请求去后端请求下拉框. 这样会导致每次都有1~2个“浏览器预请求”不通过. 浏览器为什么会自动发送“预请求”?请看以面连接 https://b ...

  2. nginx-springboot-vue前后端分离跨域配置

    nginx-springboot-vue前后端分离跨域配置 引言 接着上篇--简单的springboot-vue前后端分离登录Session拦截的demo,其中跨域是通过springboot后端全局设 ...

  3. $Django 前后端之 跨域问题(同源策略) vue项目(axios跨域请求数据)

    1 跨域问题(多个域之间的数据访问) #同源策略(ip port 协议全部相同) #本站的只能请求本站域名的数据 #CORS实现(跨域资源共享) #实现CORS通信的关键是服务器.只要服务器实现了CO ...

  4. nginx反向代理实现前后端分离&跨域问题

    1.代理和跨域 1.1 正向代理 1)用户希望代理服务器帮助其和要访问服务器之间实现通信,需要: a.用户IP报文的目的IP=代理服务器IP: b.用户报文端口号=代理服务器监听端口号: c.HTTP ...

  5. 前后端分离跨域 关于前后端分离开发环境下的跨域访问问题(angular proxy=>nginx )

    前后端分离后遇到了跨域访问的问题: angular1中使用proxy很麻烦,最后还是失败结束:最后总结3种方法如下: 本人使用的第一种方法,只是开发环境下使用很方便! 1:禁掉谷歌的安全策略(Turn ...

  6. spingsecurity 前后端分离跨域,ajax无用户信息

    1.自测时用的postman没有任何问题 2.和前端对接时发现登录不上,ajax Error 出错:{"readyState":0,"responseText" ...

  7. node与vue结合的前后端分离跨域问题

    第一点:node作为服务端提供数据接口,vue使用axios访问接口, 安装axios npm install axios --save 安装完成后在main.js中增加一下配置: import ax ...

  8. Beego和Vue的前后端分离跨域问题处理

    VUE封装的请求头(注意请求头,跨域要用到) 路径 utils/mereq.js import request from '@/utils/request' import qs from 'qs' e ...

  9. nginx配置反向代理解决前后端分离跨域问题

    摘自<AngularJS深度剖析与最佳实践>P132 nginx配置文件如下: server { listen ; server_name your.domain.name; locati ...

随机推荐

  1. nodejs通过async/await来操作MySQL

    在nodejs中从数据库得到数据后是通过回调函数来操作数据的,如果嵌套多层将非常可怕,代码逻辑和可读性将变得非常差.有时用promise也并不能很好得解决问题,因为如果用了promise后,代码将会有 ...

  2. [CSP-S模拟测试]:sum(数学+莫队)

    题目传送门(内部题63) 输入格式 第一行有一个整数$id$,表示测试点编号.第一行有一个整数$q$,表示询问组数.然后有$q$行,每行有两个整数$n_i,m_i$. 输出格式 一共有$q$行,每行一 ...

  3. Charles抓取https

    步骤一:将Charles的根证书(Charles Root Certificates)安装到Mac上. Help -> SSL Proxying -> Install Charles Ro ...

  4. 每天一个Linux指令

    开始详细系统的学习linux常用命令,坚持每天一个命令,所以这个系列为每天一个linux命令.学习的主要参考资料为: 1.<鸟哥的linux私房菜> 2.http://codingstan ...

  5. android7.0后对于file://的限制

    错误信息: 04-18 14:56:58.283  4440  4440 W System.err: android.os.FileUriExposedException: file:///stora ...

  6. leetcode 141. 环形链表(C++)

    给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. 示例 1: 输入: ...

  7. VS2012生成Web时报未能找到元数据文件xxx.dll

    问题:引用里已经添加了,还是报‘未能找到元数据文件xxx.dll’ 解决:添加了相同的不同路径的xxx.dll文件,删掉一个用不到的,就不报错了

  8. 微信小程序这一块(续)

    1.设置头部的信息 通过wx.setNavigationBarTitle 详情见:https://developers.weixin.qq.com/miniprogram/dev/api/ui/nav ...

  9. 使用多线程开启OCR

    需求:经过opencv 或者其他算法对一张图片里面的文字内容进行切割,获取到切割内容的坐标信息,再使用ocr进行识别.一张一张识别太慢了,我们可以开启多线程识别.代码如下 threads = [] f ...

  10. oracle三大范式

    范式: 设计数据库定义的一个规则, 三大范式, 灵活运用, 人的思想是活的 一范式 1, 不存在冗余数据 同一个表中的记录不能有重复----所以主键(必须有) 2, 每个字段必须是不可再分的信息(列不 ...