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 相关文章推荐
Tornado Web服务器多进程启动的2个方法
Aug 04 Python
Python实现全角半角转换的方法
Aug 18 Python
利用Fn.py库在Python中进行函数式编程
Apr 22 Python
Python操作列表之List.insert()方法的使用
May 20 Python
Python中模块pymysql查询结果后如何获取字段列表
Jun 05 Python
Django框架使用mysql视图操作示例
May 15 Python
python tkinter实现界面切换的示例代码
Jun 14 Python
Python占用的内存优化教程
Jul 28 Python
python构造函数init实例方法解析
Jan 19 Python
Python re正则表达式元字符分组()用法分享
Feb 10 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
Mar 18 Python
python和php哪个更适合写爬虫
Jun 22 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 URL跳转代码 减少外链
2011/06/25 PHP
php不用正则验证真假身份证
2013/11/06 PHP
PHP遍历目录文件的常用方法小结
2017/02/03 PHP
Yii框架学习笔记之应用组件操作示例
2019/11/13 PHP
PhpStorm2020.1 安装 debug - Postman 调用的详细教程
2020/08/17 PHP
PHP替换Word中变量并导出PDF图片的实现方法
2020/11/26 PHP
JavaScript 判断浏览器是否支持SVG的代码
2013/03/21 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
JSON对象 详解及实例代码
2016/10/18 Javascript
微信小程序 UI布局常用技巧整理总结
2016/12/05 Javascript
JS实现的自动打字效果示例
2017/03/10 Javascript
ES6中class类用法实例浅析
2017/04/06 Javascript
js图片轮播插件的封装
2017/07/21 Javascript
Node.js的Koa实现JWT用户认证方法
2018/05/05 Javascript
vue中rem的配置的方法示例
2018/08/30 Javascript
vue过滤器用法实例分析
2019/03/15 Javascript
JS实现吸顶特效
2020/01/08 Javascript
在vant中使用时间选择器和popup弹出层的操作
2020/11/04 Javascript
[07:38]2014DOTA2国际邀请赛 Newbee顺利挺进胜者组赛后专访
2014/07/15 DOTA
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
详解C++编程中一元运算符的重载
2016/01/19 Python
pandas or sql计算前后两行数据间的增值方法
2018/04/20 Python
基于Python对数据shape的常见操作详解
2018/12/25 Python
Python基于OpenCV实现人脸检测并保存
2019/07/23 Python
Ray-Ban雷朋美国官网:全球领先的太阳眼镜品牌
2016/07/20 全球购物
世界上最大的网络主机公司:1&1
2016/10/12 全球购物
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
Pureology官网:为染色头发打造最好的产品
2019/09/13 全球购物
迪卡侬印尼体育用品商店:Decathlon印尼
2020/03/11 全球购物
新闻专业学生的自我评价
2014/02/13 职场文书
小学亲子活动总结
2014/07/01 职场文书
2014年“四风”问题个人整改措施
2014/09/17 职场文书
大学开学感言
2015/08/01 职场文书
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android
python 使用tkinter与messagebox写界面和弹窗
2022/03/20 Python