一、问题背景

  之前使用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. 流氓软件修改IE主页的解决方法

    运行regedit HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main 修改以下url Default_Page_URL Firs ...

  2. UPDATE 在不同数据库中的使用方式

    MYSQL 中update 表一 set Gmoney = 表二.列名 from 表一,表二 where 表一.EMPID = 表二.EMPID举例:update table1 set table1. ...

  3. sql-hive笔试题整理 1 (学生表-成绩表-课程表-教师表)

    题记:一直在写各种sql查询语句,最长的有一百多行,自信什么需求都可以接,可......,想了想,可能一直在固定的场景下写,平时也是以满足实际需求为目的,竟不知道应试的题都是怎么出的,又应该怎么做.遂 ...

  4. Java 设计模式之 策略模式

    思维导图: 我们先来看 STRATEGY 设计模式的通俗解释: 跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,但目的都是为了得到 MM 的芳心, ...

  5. python3爬虫开发与实战预览版

    https://germey.gitbooks.io/python3webspider/content/1.2.3-ChromeDriver%E7%9A%84%E5%AE%89%E8%A3%85.ht ...

  6. HDU 4321 Arcane Numbers 2

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4321 ----------------------------------------------- ...

  7. 文件上传: FileItem类、ServletFileUpload 类、DiskFileItemFactory类

    文件上传: ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中, 在使用ServletFileUpload对象解析请求时需要根据DiskFi ...

  8. Ubuntu下使用boost例子

    http://blog.csdn.net/dotphoenix/article/details/8459277 1. 安装boost库 sudo apt-get install libboost-al ...

  9. 结合process进程,实现进程之间的通讯Queue,稍微复杂的运用

    #在父进程中创建两个子进程,一个往Queue写数据,一个从Queue里读数据 from multiprocessing import Queue,Process import time,random ...

  10. javaScript Map

                  }                   } }                          vertices.push(v);         adjList.set ...