django基于cors解决跨域请求问题详解


Posted in Python onAugust 06, 2019

一 同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现

请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.

比如:我在本地上的域名是127.0.0.1:8000,请求另外一个域名:127.0.0.1:8001一段数据

浏览器上就会报错,这个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险

已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。

但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截

二 CORS(跨域资源共享)简介

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信

三 CORS基本流程

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。

浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

四 CORS两种请求详解

只要同时满足以下两大条件,就属于简单请求。

(1)请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。

浏览器对这两种请求的处理,是不一样的。

* 简单请求和非简单请求的区别?

 简单请求:一次请求
 非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。
* 关于“预检”

- 请求方式:OPTIONS
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”
  => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
  Access-Control-Request-Method
  => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
  Access-Control-Request-Headers

支持跨域,简单请求

服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

支持跨域,复杂请求

由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers

五 Django项目中支持CORS

在返回的结果中加入允许信息(简单请求)

def test(request):
 import json
 obj=HttpResponse(json.dumps({'name':'lqz'}))
 # obj['Access-Control-Allow-Origin']='*'
 obj['Access-Control-Allow-Origin']='http://127.0.0.1:8004'
 return obj

放到中间件处理复杂和简单请求:

from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
 def process_response(self,request,response):
  if request.method=="OPTIONS":
   #可以加*
   response["Access-Control-Allow-Headers"]="Content-Type"
  response["Access-Control-Allow-Origin"] = "http://localhost:8080"
  return response

六 利用django-cors-headers模块处理

1.安装cors模块

pip install django-cors-headers

2.修改setting.py中配置

INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles', 
 'corsheaders',
]
MIDDLEWARE_CLASSES = [
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware', 
 'corsheaders.middleware.CorsMiddleware', 
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

3.添加允许访问的白名单,凡是出现在白名单的域名都可以访问后端接口

CORS_ORIGIN_WHITELIST = (
 '127.0.0.1:8080',
 'localhost:8080',
)
CORS_ALLOW_CREDENTIALS = True # 指明在跨域访问中,后端是否支持对cookie的操作。
CORS_ALLOW_METHODS = (
 'DELETE',
 'GET',
 'OPTIONS',
 'PATCH',
 'POST',
 'PUT',
 'VIEW',
)
CORS_ALLOW_HEADERS = (
 'XMLHttpRequest',
 'X_FILENAME',
 'accept-encoding',
 'authorization',
 'content-type',
 'dnt',
 'origin',
 'user-agent',
 'x-csrftoken',
 'x-requested-with',
 'Pragma',
)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Linux下编译安装MySQL-Python教程
Feb 02 Python
浅谈python中的实例方法、类方法和静态方法
Feb 17 Python
python 执行shell命令并将结果保存的实例
May 11 Python
python自动化生成IOS的图标
Nov 13 Python
python抖音表白程序源代码
Apr 07 Python
详解python实现交叉验证法与留出法
Jul 11 Python
django-rest-framework 自定义swagger过程详解
Jul 18 Python
python实现的自动发送消息功能详解
Aug 15 Python
python随机模块random使用方法详解
Feb 14 Python
使用TensorBoard进行超参数优化的实现
Jul 06 Python
Python爬虫之爬取淘女郎照片示例详解
Jul 28 Python
Python爬虫数据的分类及json数据使用小结
Mar 29 Python
django组合搜索实现过程详解(附代码)
Aug 06 #Python
使用Python自动生成HTML的方法示例
Aug 06 #Python
Django RBAC权限管理设计过程详解
Aug 06 #Python
python虚拟环境完美部署教程
Aug 06 #Python
python批量图片处理简单示例
Aug 06 #Python
Python实用库 PrettyTable 学习笔记
Aug 06 #Python
浅谈django2.0 ForeignKey参数的变化
Aug 06 #Python
You might like
php下实现一个阿拉伯数字转中文数字的函数
2008/07/10 PHP
基于PHP异步执行的常用方式详解
2013/06/03 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
PHP切割整数工具类似微信红包金额分配的思路详解
2019/09/18 PHP
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
jquery控制select的text/value值为选中状态
2014/06/03 Javascript
JS获取CSS样式(style/getComputedStyle/currentStyle)
2016/01/19 Javascript
轻松搞定jQuery.noConflict()
2016/02/15 Javascript
AngularJS入门教程之AngularJS表达式
2016/04/18 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
js实现动态创建的元素绑定事件
2016/07/19 Javascript
Bootstrap和Angularjs配合自制弹框的实例代码
2016/08/24 Javascript
jquery删除table当前行的实例代码
2016/10/07 Javascript
jQuery绑定事件的四种方式介绍
2016/10/31 Javascript
详解node nvm进行node多版本管理
2017/10/21 Javascript
Angular4.x通过路由守卫进行路由重定向实现根据条件跳转到相应的页面(推荐)
2018/05/10 Javascript
JavaScript实现鼠标移入随机变换颜色
2020/11/24 Javascript
[03:01]完美世界DOTA2联赛PWL S2 集锦第二期
2020/12/03 DOTA
python连接池实现示例程序
2013/11/26 Python
用smtplib和email封装python发送邮件模块类分享
2014/02/17 Python
python访问类中docstring注释的实现方法
2015/05/04 Python
Python3.6简单反射操作示例
2018/06/14 Python
pandas 缺失值与空值处理的实现方法
2019/10/12 Python
python实现连续变量最优分箱详解--CART算法
2019/11/22 Python
Python远程开发环境部署与调试过程图解
2019/12/09 Python
Python如何输出整数
2020/06/07 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
python3处理word文档实例分析
2020/12/01 Python
Html5原生拖拽相关事件简介以及基础实现
2020/11/19 HTML / CSS
法国家具及室内配件店:home24
2017/01/21 全球购物
俄罗斯GamePark游戏商店网站:购买游戏、游戏机和配件
2020/03/13 全球购物
建筑施工实习自我鉴定
2013/09/19 职场文书
党员廉洁自律承诺书
2014/05/26 职场文书
国贸专业毕业求职信
2014/06/11 职场文书
单位接收函范文
2015/01/30 职场文书
社区文明创建工作总结2015
2015/04/21 职场文书