一、问题背景

  之前使用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. [super class]和[self class]

    参考: https://www.jianshu.com/p/3f2bcc588b44?utm_campaign=hugo&utm_medium=reader_share&utm_con ...

  2. Java-访问控制权限

    Java面向对象-访问控制权限 Java中,可以通过一些Java关键字,来设置访问控制权限: 主要有 private(私有), package(包访问权限),protected(子类访问权限),pub ...

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

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

  4. 像计算机科学家一样思考python-第2章 变量、表达式和语句

    感想: 1.程序出现语义错误时,画状态图是一个很好的调试办法.打印出关键变量在不同代码处理后值的变化,就能发现问题的蛛丝马迹. 2.每当学习新语言特性时,都应当在交互模式中进行尝试,并故意犯下错误,看 ...

  5. C++ 编写的DLL导出的函数名乱码含义解析

    C++编译时函数名修饰约定规则: __stdcall调用约定:   1.以"?"标识函数名的开始,后跟函数名:     2.函数名后面以"@@YG"标识参数表的 ...

  6. Nginx 模块 - ngx_core_module

    原文地址 示例配置 指令 accept_mutex accept_mutex_delay daemon debug_connection debug_points env error_log even ...

  7. vue同意本站协议的制作

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Python几行代码实现邮件发送

    话不多说直接进入正题 首先我们需要安装一个名为'zmail'的包,终端执行'pip install zmail'即可实现安装. 直接上代码 import zmail mail = { 'subject ...

  9. mac下使用iterm实现自动登陆

    1.通过brew安装sshpass(手动安装也可以) ①brew安装sshpass brew install https://raw.githubusercontent.com/kadwanev/bi ...

  10. web开发jsp页面遇到的一系列问题

    一:web总结 1.jsp页面知识点巩固 1.1字符串数字格式化转换 <%@ taglib prefix="fmt" uri="http://java.sun.co ...