Django跨域请求原理及实现代码


Posted in Python onNovember 14, 2020

一 同源策略

同源策略(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) 请求方法是以下三种方法之一:

  1. HEAD
  2. GET
  3. POST

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

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID

Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

创建两个Django项目:简单请求:get、application/x-www-form-urlencoded

mysite1项目---------127.0.0.0:8008 (8008向8006端口发送简单请求)

views.py

from django.shortcuts import render
# Create your views here.
def test(request):
  return render(request,'index.html')

template/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <script src="/static/jquery-3.3.1.js"></script>
  <title>Title</title>
</head>
<body>
<button id="mybutton">点我</button>
</body>
<script>

  $("#mybutton").click(function () {
    $.ajax({
      url:'http://127.0.0.1:8006/mytest',  #向该ip端口发送一个get的简单请求
      type:'get',
      success:function (data) {
        console.log(data)
      }
    })
  })
</script>
</html>

mysite2项目---------127.0.0.0:8006

views.py

def mytest(request):
  import json
  print('111')
  obj = HttpResponse(json.dumps({'name': 'lqz'}))
  # if request.method=='OPTIONS':
  #   obj['Access-Control-Allow-Methods']='PUT'
  #   obj['Access-Control-Allow-Headers']='k1'
  #
  #
  # # obj['Access-Control-Allow-Origin']='http://127.0.0.1:8008'
  # obj['Access-Control-Allow-Origin']='*'
  return obj

Django跨域请求原理及实现代码

就是由于同源策略被被浏览器阻止了,所以请求没有成功返回数据(其实数据已经从服务器成功请求回来,只是由于同源策略请求成功的数据被浏览器阻止了)

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

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

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

简单请求:一次请求

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

* 关于“预检”

- 请求方式: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

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

Python 相关文章推荐
python应用程序在windows下不出现cmd窗口的办法
May 29 Python
python提取页面内url列表的方法
May 25 Python
python使用win32com库播放mp3文件的方法
May 30 Python
python实现读Excel写入.txt的方法
Apr 29 Python
深入理解Python中的 __new__ 和 __init__及区别介绍
Sep 17 Python
Python 处理图片像素点的实例
Jan 08 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
Jun 11 Python
使用Fabric自动化部署Django项目的实现
Sep 27 Python
使用python创建生成动态链接库dll的方法
May 09 Python
Python列表元素删除和remove()方法详解
Jan 04 Python
Python数据分析入门之教你怎么搭建环境
May 13 Python
什么是Python装饰器?如何定义和使用?
Apr 11 Python
Pycharm如何自动生成头文件注释
Nov 14 #Python
分布式全文检索引擎ElasticSearch原理及使用实例
Nov 14 #Python
Django websocket原理及功能实现代码
Nov 14 #Python
Pycharm常用快捷键总结及配置方法
Nov 14 #Python
Django model class Meta原理解析
Nov 14 #Python
详解python爬取弹幕与数据分析
Nov 14 #Python
Ubuntu权限不足无法创建文件夹解决方案
Nov 14 #Python
You might like
PHP中读写文件实现代码
2011/10/20 PHP
YII中assets的使用示例
2014/07/31 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
jqueryUI里拖拽排序示例分析
2015/02/26 Javascript
jQuery实现带有洗牌效果的动画分页实例
2015/08/31 Javascript
angular 动态组件类型详解(四种组件类型)
2017/02/22 Javascript
BootStrap Select清除选中的状态恢复默认状态
2017/06/20 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
2017/09/19 jQuery
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
Vue搭建后台系统需要注意的问题
2019/11/08 Javascript
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
VsCode里的Vue模板的实现
2020/08/12 Javascript
Ant-design-vue Table组件customRow属性的使用说明
2020/10/28 Javascript
python3安装pip3(install pip3 for python 3.x)
2018/04/03 Python
python/sympy求解矩阵方程的方法
2018/11/08 Python
python抓取需要扫微信登陆页面
2019/04/29 Python
numpy.linspace函数具体使用详解
2019/05/27 Python
PyQt5 窗口切换与自定义对话框的实例
2019/06/20 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
pyqt5 QlistView列表显示的实现示例
2020/03/24 Python
keras 解决加载lstm+crf模型出错的问题
2020/06/10 Python
Python下划线5种含义代码实例解析
2020/07/10 Python
基于python requests selenium爬取excel vba过程解析
2020/08/12 Python
详解pytorch tensor和ndarray转换相关总结
2020/09/03 Python
CSS实现进度条和订单进度条的示例
2020/11/05 HTML / CSS
FOREO官方网站:LUNA露娜洁面仪
2016/11/28 全球购物
小米旗下精品生活电商平台:小米有品
2018/12/18 全球购物
大学生求职简历的自我评价范文
2013/10/12 职场文书
医学专业本科毕业生自我鉴定
2013/12/28 职场文书
幼儿园教师工作制度
2014/01/22 职场文书
入党申请自荐书范文
2014/02/11 职场文书
会计工作总结范文2014
2014/12/23 职场文书
2015年个人工作总结报告
2015/04/25 职场文书
Python使用UDP实现720p视频传输的操作
2021/04/24 Python
Oracle数据库中通用的函数实例详解
2022/03/25 Oracle