django中的跨域问题以及解决策略

2023-11-09

目录

跨域请求

同源策略

CORS(跨域资源共享)简介

CORS基本流程

解决跨域问题的方法

CORS两种请求详解

预检:

解决跨域问题(服务端)

简单请求

 非简单请求

解决跨域问题(第三方)

后端配置

解决跨域问题(前端)


跨域请求

跨域是指浏览器不能执行其他网站的脚本, 它是由浏览器的同源策略造成的,,是浏览器对javascript 实施的安全限制。 

浏览器从一个域名的网页请求去另一个域名的资源时,出现域名,端口,协议任意一个不同就属于跨域

部署时前后端不分离可以解决此问题【但是不推荐】

同源策略

同源策略是浏览器为了保护用户信息安全的一种安全政策。 指的是iu篮球页面的协议, 域名,端口号都相同,其目的是为了保证用户的信息安全,防止恶意网站盗取数据信息。 

不同源的客户端脚本js在没有得到服务端的明确授权的情况下,浏览器会显示拒绝提供服务给前端ajax/axios。

CORS(跨域资源共享)简介

CORS是一个W3C标准,全程跨域资源共享。 它允许浏览器向跨源的后端服务器发出ajax请求,

从而克服了AJAX只能同源使用的限制。

实现CORS主要一开后端服务器响应数据中设置响应头信息返回的CORS需要浏览器和服务器同时支持, 目前除了IE浏览器都支持该功能

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

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

容易混淆的点:

  • CORS:跨域资源共享
  • CSRF: 跨站请求伪造
  • XSS: 跨站脚本攻击

CORS基本流程

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

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

浏览器发出非简单CORS请求, 会在正式通信之前增加一次Http查询请求,即’预检‘请求。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之内,以及跨源使用那些Http动词和头信息字段

只有的带肯定答复,溜啦冷凝器才会发出正式的XMLHttpRequest请求,否则就会报错。 

解决跨域问题的方法

前端: 通过代理解决

nginx代理

cors解决跨域:django-cors-headers

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

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

json格式是非简单请求

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

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

简单请求:之发送一次请求

非简单请求: 发送2次请求,在发送数据之前会先发一次请求用于做’预检‘看后端是否允许,只有预检通过之后才会再次发送请求用于数据传输

请求方式OPTIONS

预检:

如果非简单请求是PUT等请求, 则服务端需要设置允许某请求,否则预检不通过

  • Access-Control-Request-Method

如果非简单请求设置了请求头, 则服务端需要设置允许某请求头,否则预检不通过

  • Access-Control-Request-Headers

解决跨域问题(服务端)

简单请求

Django项目: apps/user/views.py

from django.http import JsonResponse


def test(request):
    obj = JsonResponse({'name': 'darker', 'age': '18'})
    # 值针对简单请求
    obj['Access-Control-Allow-Origin'] = '*'    # 允许所有IP访问
    return obj

2, 原 django项目: apps/user/urls.py

from django.urls import path
from user import views

urlpatterns = [
    path('test/', views.test),
]

3. django项目中注释掉dev.py中的CSRF

4, 再创建一个django项目(用另一个端口)

template中创建index。html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button id="btn">点我</button>

</body>
<script>
    $('#btn').click(function () {
        $.ajax({
            url: 'http://127.0.0.1:8000/user/test/',
            method: 'get',
            success: function (data) {
                console.log(data)
            }
        })
    })
</script>
</html>

views.py

from django.shortcuts import render


def index(request):
    return render(request, 'index.html')

urls.py

from django.urls import path
from app01 import views

urlpatterns = [
    path('test/', views.index),
]

 非简单请求

原django项目 app/user/view.py

from django.http import JsonResponse


def test(request):
    obj = JsonResponse({'name': 'Darker', 'age': '18'})
    if request.method == 'OPTIONS':
        obj['Access-Control-Allow-Headers'] = 'Content-Type,authorization'  # 或者填写 *
    obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8002'    # 8002端口是当前项目的
    return obj

 新django项目中 template/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button id="btn">点我</button>

</body>
<script>
    $('#btn').click(function () {
        let obj = {name: 'Darker'}
        $.ajax({
            url: 'http://127.0.0.1:8000/user/test/',
            method: 'post',
            contentType: 'application/json',
            headers: {authorization: 'Darker'},
            data: JSON.stringify(obj),
            success: function (data) {
                console.log(data)
            }
        })
    })
</script>
</html>

 3, 中间件处理

① 在原Django项目的根路径创建mymiddle.py - 自定义中间件

from django.utils.deprecation import MiddlewareMixin


class CoreMiddle(MiddlewareMixin):
    def process_response(self, request, response):
        if request.method == 'OPTIONS':
            response['Access-Control-Allow-Headers'] = 'Content-Type, authorization'    # 如果是 * 就代表全部IP都可以访问
        response['Access-Control-Allow-Origin'] = '*'
        return response

② 在原Django项目的dev.py的中间件中添加自定义中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'mymiddle.CoreMiddle',    # 这一句
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

③ 原Django项目apps/user/views中替换成如下代码

from django.http import JsonResponse


def test(request):
    return JsonResponse({'name': 'Darker', 'age': '18'})

解决跨域问题(第三方)

后端配置

① 后端安装跨域模块

pip install django-cors-headers

2, 到dev.py中注册

INSTALLED_APPS = (
    ...
    'corsheaders'
)

3  到dev.py中添加中间件

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',    # 这个是原本就存在的
    ...
]

④ 到dev.py中添加如下代码

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
# CORS_ORIGIN_WHITELIST = (
#     'http://127.0.0.1:8080',
# )
CORS_ALLOWED_ORIGINS_REGEXES=[
    r'^http://.*?$',
]
# CORS_ORIGIN_REGEXES_WHITELIST = (
#         r'^http://.*?$',
# )
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',
)

 设置dev.pyALLOWED_HOSTS

ALLOWED_HOSTS = ['*']

后端测试

(测试 - 后台)到apps/user/views中替换成如下代码

from django.http import JsonResponse


def test(request):
    return JsonResponse({'name': 'Darker', 'age': '18'})

(测试 - 后台)到apps/user/urls中替换成如下代码

from django.urls import path
from user import views

urlpatterns = [
    path('test/', views.test),
]

启动项目

python manage.py runserver 127.0.0.1:8000

 访问测试

前端测试

(测试 - 前台)App.vue 中换成如下代码

<template>
  <div id="app">
    <router-view/>
    {{name}}
  </div>
</template>

<script>
export default {
  data () {
    return {
      name: []
    }
  },
  mounted () {
    this.$axios.get(this.$settings.base_url + '/user/test/').then(res => {
      this.name = res.data
    })
  }
}
</script>

 启动项目

npm run serve

解决跨域问题(前端)

前端App.vue

<template>
  <div id="home">
    <h1>我是主页</h1>
    <h2>{{info}}</h2>
  </div>
</template>

<script>
export default {
  name: 'Home',
  data () {
    return {
      info: []
    }
  },
  mounted () {
    this.$axios.get('/moreClassicList?sortId=1&showType=3').then(res => {
      console.log(res.data)
    })
  }
}
</script>

<style scoped>

</style>

前端项目根路径 vue.config.js

const webpack = require("webpack");

module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery",
        "window.$": "jquery",
        Popper: ["popper.js", "default"]
      })
    ]
  },
  devServer: {
    proxy: {
      '/ajax': {
        target: 'https://m.maoyan.com/',
        changeOrigin: true
      },
      '/user': {
        target: 'http://127.0.0.1:8000',
        changeOrigin: true
      }
    }
  }
};

 wsgi,uWSGI,uwsgi

https://www.liuqingzheng.top/article/1/05-CGI,FastCGI,WSGI,uWSGI,uwsgi%E4%B8%80%E6%96%87%E6%90%9E%E6%87%82/

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

django中的跨域问题以及解决策略 的相关文章

  • 在 Celery 任务中调用 Google Cloud API 永远不会返回

    我正在尝试拨打外部电话Google Cloud Natural Language API从一个内Celery任务 使用google cloud python包裹 问题是对 API 的调用永远不会返回 挂起 celery task def g
  • pandas DataFrame.join 的运行时间是多少(大“O”顺序)?

    这个问题更具概念性 理论性 与非常大的数据集的运行时间有关 所以我很抱歉没有一个最小的例子来展示 我有一堆来自两个不同传感器的数据帧 我需要最终将它们连接成两个very来自两个不同传感器的大数据帧 df snsr1 and df snsr2
  • NLTK 2.0分类器批量分类器方法

    当我运行此代码时 它会抛出一个错误 我认为这是由于 NLTK 3 0 中不存在batch classify 方法 我很好奇如何解决旧版本中的某些内容在新版本中消失的此类问题 def accuracy classifier gold resu
  • 嵌套列表的重叠会产生不必要的间隙

    我有一个包含三个列表的嵌套 这些列表由 for 循环填充 并且填充由 if 条件控制 第一次迭代后 它可能类似于以下示例 a 1 2 0 0 0 0 0 0 4 5 0 0 0 0 0 0 6 7 根据条件 它们不重叠 在第二次迭代之后 新
  • 在 Django Admin 中调整字段大小

    在管理上添加或编辑条目时 Django 倾向于填充水平空间 但在某些情况下 当编辑 8 个字符宽的日期字段或 6 或 8 个字符的 CharField 时 这确实是一种空间浪费 字符宽 然后编辑框最多可容纳 15 或 20 个字符 我如何告
  • 打印数字时添加千位分隔符[重复]

    这个问题在这里已经有答案了 我真的不知道这个问题的 名称 所以它可能是一个不正确的标题 但问题很简单 如果我有一个数字 例如 number 23543 second 68471243 我想要它使print 像这样 23 54368 471
  • 打印包含字符串和其他 2 个变量的变量

    var a 8 var b 3 var c hello my name is var a and var b bye print var c 当我运行程序时 var c 会像这样打印出来 hello my name is 8 and 3 b
  • 从 Powershell 脚本安装 Python

    当以管理员身份从 PowerShell 命令行运行以下命令时 可以在 Windows 11 上成功安装 Python c temp python 3 11 4 amd64 exe quiet InstallAllUsers 0 Instal
  • 使用 python/numpy 重塑数组

    我想重塑以下数组 gt gt gt test array 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44 为了得到 gt gt gt test2 array 11 12 21 22 13 14
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序
  • Pandas 组合不同索引的数据帧

    我有两个数据框df 1 and df 2具有不同的索引和列 但是 有一些索引和列重叠 我创建了一个数据框df索引和列的并集 因此不存在重复的索引或列 我想填写数据框df通过以下方式 for x in df index for y in df
  • 找到一个数字所属的一组范围

    我有一个 200k 行的数字范围列表 例如开始位置 停止位置 该列表包括除了非重叠的重叠之外的所有类型的重叠 列表看起来像这样 3 5 10 30 15 25 5 15 25 35 我需要找到给定数字所属的范围 并对 100k 个数字重复该
  • python 中的“槽包装器”是什么?

    object dict 和其他地方的隐藏方法设置为这样的
  • 每当使用 import cv2 时 OpenCV 都会出错

    我在终端上使用 pip3 install opencv contrib python 安装了 cv2 并且它工作了 但是每当我尝试导入 cv2 或运行导入了 cv2 的 vscode 文件时 在 python IDLE 上它都会说 Trac
  • 重新分配唯一值 - pandas DataFrame

    我在尝试着assign unique值在pandas df给特定的个人 For the df below Area and Place 会一起弥补unique不同的价值观jobs 这些值将分配给个人 总体目标是使用尽可能少的个人 诀窍在于这
  • 如何使用 Boto3 启动具有 IAM 角色的 EC2 实例?

    我无法弄清楚如何使用指定的 IAM 角色在 Boto3 中启动 EC2 实例 以下是迄今为止我如何成功创建实例的一些示例代码 import boto3 ec2 boto3 resource ec2 region name us west 2
  • 如何将 Django 中的权限添加到模型并使用 shell 进行测试

    我在模型中添加了 Meta 类并同步了数据库 然后在 shell 中创建了一个对象 它返回 false 所以我真的无法理解错误在哪里或者缺少什么是否在其他文件中可能存在某种配置 class Employer User Employer in
  • pandas.read_csv 将列名移动一倍

    我正在使用位于的 ALL zip 文件here http www fec gov disclosurep PDownload do 我的目标是用它创建一个 pandas DataFrame 但是 如果我跑 data pd read csv
  • 将索引与值交换的最快方法

    考虑pd Series s s pd Series list abcdefghij list ABCDEFGHIJ s A a B b C c D d E e F f G g H h I i J j dtype object 交换索引和值并
  • python 对浮点数进行不正确的舍入

    gt gt gt a 0 3135 gt gt gt print 3f a 0 314 gt gt gt a 0 3125 gt gt gt print 3f a 0 312 gt gt gt 我期待 0 313 而不是 0 312 有没有

随机推荐

  • 管理后台项目-06-用户管理角色管理模块

    目录 1 路由信息搭建和api文件信息创建 2 用户管理模块 2 1 列表数据获取以及动态渲染 2 2 添加 修改 用户 2 3 删除 批量删除用户 2 4 分配角色 3 角色管理 3 1 修改角色 3 2 分配权限 1 路由信息搭建和ap
  • vue $nextTick()方法实现原理

    什么是 nextTick 在下次 DOM 更新循环结束之后执行延迟回调 简单的理解是 当数据更新了 在dom中渲染后 自动执行该函数 原理 1 nextTick就是一个异步方法 nextTick 方法主要是使用了宏任务或微任务 事件循环机制
  • C++ 特化与重载(12)---《C++ Templates》

    目前为止 我们已经学习了C 如何使一个泛型定义被展开为一族系相关的classes或者function 但是这远远不够 以一个特定替换物取代泛华的templates parameters远远达不到优化的要求 因此 本片中我们将介绍两种机制 用
  • 伺服电机三环(电流环、速度环、位置环)控制原理及参数调节

    原文 https blog csdn net sunjiajiang article details 8252026 运动伺服一般都是三环控制系统 从内到外依次是电流环 速度环 位置环 1 电流环 电流环的输入是速度环PID调节后的输出 我
  • 设计模式(四) 建造者模式

    建造者模式和工厂模式类似 也是一种创建型模式 它们的主要区别在于 工厂模式需要提供一些信息 而对象在最后一步才创建 而建造者模式则是一步一步的创建对象 一个非常典型的建造者的例子是Java中的StringBuilder 通过一步一步的添加字
  • Journal of Proteome Research

    期刊名 Journal of Proteome Research 发表时间 2019年9月 IF 3 78 2018 单位 巴塞尔大学 瑞士 物种 人细胞系 技术 冷冻电子显微镜 Cryo EM 单粒子电子显微镜 一 概述 本文描述了一种
  • C语言的字符串查找函数

    C C string库 string h 提供了几个字符串查找函数 如下 memchr 在指定内存里定位给定字符 strchr 在指定字符串里定位给定字符 strcspn 返回在字符串str1里找到字符串str2里的任意一个字符之前已查找的
  • arma模型matlab代码_时间序列分析ARMA模型(金融计量一)

    以下内容为原创 如有错误请联系纠正 联系作者方式 微信公众号 计量文学 公众号会发布计量学相关文章 软件安装教程 公众号刚起步 希望多多支持 作业说明 1 给出原序列折线图 并加以文字描述 2 给出原序列或差分序列 如果有需要 的自相关函数
  • 深入剖析Kubernetes之声明式 API

    文章目录 声明式 API 编写自定义控制器 声明式 API 到底什么才是 声明式 API 呢 kubectl apply 命令 kubectl replace 的执行过程 是使用新的 YAML 文件中的 API 对象 替换原有的 API 对
  • Vue-Router总结

    路由三大组成部分 router link 导航 link 标签 router view 路由视图 路由页面呈现的地方 new VueRouter 路由配置 routes router link属性 1 to进行页面跳转 更改路径 2 tag
  • 着手MQTT.fx软件应用,利于深入了解MQTT协议数据连接、传递、订阅/发布流程

    第一步 Extras gt Edit connection 第二步 添加连接信息 第三步 选择连接的服务器 第四步 点击连接 成功就变为绿色 第五步 订阅 第六步 发布 第七步 查看订阅数据 这大致就是一个基本的使用过程 MQTT fx的下
  • 软件工程毕业设计题目合集【含源码+论文】

    文章目录 前言 题目1 基于SSM的房屋出租出售系统 br 题目2 基于SSM的房屋租赁系统 br 题目3 基于SSM的个人健康信息管理系统 br 题目4 基于SSM的共享充电宝管理系统 br 题目5 基于SSM的即动运动网站 br 前言
  • 操作系统期末整理!!!重要!!

    操作系统 期末可以过啦 第一章 操作系统引论 1 操作系统的定义 2 操作系统的作用 3 操作系统发展过程 4 各类型操作系统的特点 5 操作系统的基本特征 6 操作系统的基本功能 7 异常和中断的区别 8 为什么说中断是操作系统的核心技术
  • Keil报: warning: #223-D: function “某某某“ declared implicitly 的警告,三个解决方法

    原因 找不到 某某某 函数 解决 看有没有 include 相关头文件 看函数定义有没有出错 函数定义有一点不同就会出现上述原因 我个人遇到的比较奇葩的原因 emmm 人比较奇葩吧 在两个不同的 h文件中写了相同的 ifndef INA H
  • led灯条串联图_三分钟学会DIY个性LED灯

    上篇文章介绍了LED光源 主要介绍LED结构 常用参数 型号 常见品牌等内容 回看的小伙伴请点击照明灯饰专栏 今天主要介绍LED灯的工作原理与常见的LED灯 明白之后DIY自己的个性LED毫无压力 先别跳过下面有干货 一 LED驱动 上篇文
  • GoogLeNet论文阅读笔记

    目录 前言 GoogLeNet论文阅读笔记 Abstract 1 Introduction 2 Related Work 3 Motivation and High Level Considerations 4 Architectural
  • 上升沿_输入输出的上升沿和下降沿是怎么来的,一起看看

    高电平 低电平 上升沿和下降沿的区别 数字电路中 电平从低电平 逻辑信号为0 变为高电平 逻辑信号为1 的那一瞬间叫作上升沿 电平从高电平 逻辑信号为1 变为低电平 逻辑信号为0 的那一瞬间叫作下降沿 高电平触发 是指I O口电平为高电平时
  • Java实现给定两个 int 变量, 交换变量的值

    给定两个 int 变量 交换变量的值 1 创建变量i实现交换 2 不创建临时变量利用加减法实现 public class Solution public static void main String args int a 10 int b
  • C++ C2460 error

    关于该错误的官方说明 https msdn microsoft com en us library 1kf0205c aspx 结构形如 identifier1 uses identifier2 类或结构 identifier2 被声明为其
  • django中的跨域问题以及解决策略

    目录 跨域请求 同源策略 CORS 跨域资源共享 简介 CORS基本流程 解决跨域问题的方法 CORS两种请求详解 预检 解决跨域问题 服务端 简单请求 非简单请求 解决跨域问题 第三方 后端配置 解决跨域问题 前端 跨域请求 跨域是指浏览