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写的一个简单DNS服务器实例
Jun 04 Python
python复制文件的方法实例详解
May 22 Python
Python使用tablib生成excel文件的简单实现方法
Mar 16 Python
利用Python自动监控网站并发送邮件告警的方法
Aug 24 Python
Python科学计算包numpy用法实例详解
Feb 08 Python
Python绘制KS曲线的实现方法
Aug 13 Python
Python实现统计英文文章词频的方法分析
Jan 28 Python
python多线程+代理池爬取天天基金网、股票数据过程解析
Aug 13 Python
python集合删除多种方法详解
Feb 10 Python
Python Django2 model 查询介绍(条件、范围、模糊查询)
Mar 16 Python
如何使用python记录室友的抖音在线时间
Jun 29 Python
详解python实现可视化的MD5、sha256哈希加密小工具
Sep 14 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获取数组元素中头一个数组元素值的实现方法
2014/12/20 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
2018/08/04 PHP
js的逻辑运算符 ||
2010/05/31 Javascript
Bookmarklet实现启动jQuery(模仿 云输入法)
2010/09/15 Javascript
showModalDialog在谷歌浏览器下会返回Null的解决方法
2013/11/27 Javascript
jquery数组之存放checkbox全选值示例代码
2013/12/20 Javascript
Jquery 获取指定标签的对象及属性的设置与移除
2014/05/29 Javascript
node.js中的console.time方法使用说明
2014/12/09 Javascript
简单谈谈javascript Date类型
2015/09/06 Javascript
jQuery实现鼠标双击Table单元格变成文本框及输入内容后更新到数据库的方法
2015/11/25 Javascript
多种js图片预加载实现方式分享
2016/02/19 Javascript
jQuery实现点击查看大图并以弹框的形式居中
2016/08/08 Javascript
Javascript的this用法
2017/01/16 Javascript
如何将 jQuery 从你的 Bootstrap 项目中移除(取而代之使用Vue.js)
2017/07/17 jQuery
JS鼠标3次点击事件实现代码及扩展思路
2017/09/12 Javascript
Vue中rem与postcss-pxtorem的应用详解
2019/11/20 Javascript
前端开发之便利店收银系统代码
2019/12/27 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
2020/07/31 Javascript
[08:54]《一刀刀一天》之DOTA全时刻18:十九支奔赴西雅图队伍全部出炉
2014/06/04 DOTA
使用python 获取进程pid号的方法
2014/03/10 Python
Python中if __name__ == &quot;__main__&quot;详细解释
2014/10/21 Python
Django开发中复选框用法示例
2018/03/20 Python
数组保存为txt, npy, csv 文件, 数组遍历enumerate的方法
2018/07/09 Python
Django1.11自带分页器paginator的使用方法
2019/10/31 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
英国领先的高街书籍专家:Waterstones
2018/02/01 全球购物
英国首屈一指的票务公司:See Tickets
2019/05/11 全球购物
普师专业个人自荐信范文
2013/11/26 职场文书
创业计划书——互联网商机
2014/01/12 职场文书
年度考核自我鉴定
2014/02/02 职场文书
2014小学一年级班主任工作总结
2014/12/05 职场文书
爱心捐款感谢信
2015/01/20 职场文书
公司处罚决定书
2015/06/24 职场文书
python process模块的使用简介
2021/05/14 Python
python 开心网和豆瓣日记爬取的小爬虫
2021/05/29 Python
MySQL的意向共享锁、意向排它锁和死锁
2022/07/15 MySQL