Django前后端打通

跨域问题

【 0 】前言

image-20240511083754769

​ 同源策略(Same Origin Policy)是浏览器安全策略的重要组成部分,它限制了来自不同源的网页之间的数据交互,以防止恶意攻击。当一个网页尝试执行与它的源(即协议、域名和端口)不一致的请求时,浏览器会出于安全考虑拦截这个请求。

​ 跨域资源共享(CORS, Cross-Origin Resource Sharing)是一个W3C规范,它允许某些跨源请求,如Ajax,从而克服了Ajax只能同源使用的限制。CORS需要浏览器和服务器同时支持,基本思想是使用自定义的HTTP头来让浏览器和服务器进行通信。

​ 在Django项目中解决跨域问题,可以通过多种方法,包括手动编写中间件以及使用第三方库。你给出的示例展示了如何手动编写一个CORS中间件,以及如何使用django-cors-headers这个流行的第三方库来简化CORS的设置。

手动编写CORS中间件

​ 中间件代码示例中,通过向响应头中添加适当的CORS相关头部,允许来自任何源的请求("Access-Control-Allow-Origin": "*")。同时,对于OPTIONS请求(预检请求),该中间件还允许所有的方法和头部。

使用django-cors-headers

  1. 安装库:pip install django-cors-headers
  2. settings.py中添加'corsheaders'INSTALLED_APPS
  3. settings.pyMIDDLEWARE中添加'corsheaders.middleware.CorsMiddleware',并确保它在其他中间件之前(特别是在CommonMiddleware之前)。
  4. 配置CORS选项。例如,设置CORS_ORIGIN_ALLOW_ALLTrue来允许所有源的请求,或者你可以指定一个允许源的列表。CORS_ALLOW_METHODSCORS_ALLOW_HEADERS分别定义了允许的HTTP方法和头部。

​ 请注意,出于安全考虑,通常不建议在生产环境中设置CORS_ORIGIN_ALLOW_ALLTrue,除非你完全理解可能的安全风险。在生产环境中,最好明确指定允许的源。

​ 另外,值得注意的是,虽然CORS解决了浏览器端的跨域问题,但服务器端仍然需要验证请求的有效性,以防止潜在的安全威胁,如CSRF攻击。因此,即使启用了CORS,也不应忽视服务器端的安全性措施。

# 同源策略(Same origin policy)是一种约定,它规定了 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同,如果不一致,请求会发送成功,后端会正常响应,但是浏览器会拦截#  浏览器对非同源请求返回的结果做了拦截
# 只要做前后端分离,就会出跨域# 解决跨域问题-CORS :跨域资源共享  咱们讲的方式   向响应头中加数据,允许跨域- 后端代码处理- nginx代理-JSONP :利用有的标签没有跨域问题 script  img-websocket:长链接,不存在跨域-前端代理:开发阶段用,上线不用# cors如何解决跨域-需要服务端支持---》就是服务端再响应头中加数据即可# CORS基本流程CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)简单请求,只发送一次:非简单请求发送两次,第一次是OPTIONS预检请求,第二次是真正的请求
# 什么是简单,什么是非简单
#请求方法是以下三种方法之一:HEADGETPOST
# HTTP的头信息不超出以下几种字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain# 请求头中带了 token ,所有请求都是非简单### 解决跨域---统一写个中间件--》处理所有跨域
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):def process_response(self,request,response):if request.method=="OPTIONS":#可以加*response["Access-Control-Allow-Headers"]="*"res['Access-Control-Allow-Methods'] = '*'response["Access-Control-Allow-Origin"] = "*"return response# 第三方解决方案# 1、使用pip安装pip install django-cors-headers#2、添加到setting的app中INSTALLED_APPS = (...'corsheaders',...)#3、添加中间件MIDDLEWARE = [  ...'corsheaders.middleware.CorsMiddleware',...]
4、setting下面添加下面的配置
CORS_ORIGIN_ALLOW_ALL = True
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','token'
)

【 1 】解释

Access-Control-Allow-HeadersAccess-Control-Allow-MethodsAccess-Control-Allow-Origin 是三个与跨源资源共享(CORS)相关的 HTTP 响应头。它们各自有不同的作用和使用方法。

1. Access-Control-Allow-Origin

作用

  • 用于指定哪些源(域名、协议和端口)有权限访问该资源。

使用方法

  • 如果服务器希望允许来自特定源的请求,如 https://example.com,可以返回以下响应头:
Access-Control-Allow-Origin: https://example.com
  • 如果服务器希望允许来自任何源的请求(这通常在生产环境中是不安全的),可以返回:
Access-Control-Allow-Origin: *

2. Access-Control-Allow-Methods

作用

  • 列出哪些 HTTP 方法(如 GET、POST、PUT、DELETE 等)允许跨源请求。

使用方法

  • 如果服务器只允许 GET 和 POST 方法,可以返回以下响应头:
Access-Control-Allow-Methods: GET, POST
  • 这个响应头通常与预检请求(OPTIONS 请求)一起使用,以检查服务器是否允许跨源请求中使用的特定 HTTP 方法。

3. Access-Control-Allow-Headers

作用

  • 用于告知浏览器在跨域请求中,所允许的请求头字段(Request Header)。

使用方法

  • 如果浏览器请求包括 Access-Control-Request-Headers 字段,则 Access-Control-Allow-Headers 字段是必需的。它的值是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在“预检”中请求的字段。
  • 例如,如果服务器允许跨域请求时使用的请求头字段是 Content-TypeAuthorization,可以返回以下响应头:
Access-Control-Allow-Headers: Content-Type, Authorization

总结

  • Access-Control-Allow-Origin 用于指定哪些源可以访问资源。
  • Access-Control-Allow-Methods 用于指定哪些 HTTP 方法允许跨源请求。
  • Access-Control-Allow-Headers 用于告知浏览器在跨域请求中,所允许的请求头字段。

​ 这三个响应头通常一起使用,以确保跨源请求的安全性和可访问性。同时,它们也遵循 CORS 规范,确保浏览器和服务器之间的正确交互。

【 2 】跨域问题

【 1 】笨办法

  • Access-Control-Allow-Origin

  • 在子路由的视图类

from rest_framework.views import APIView
from lufy.utils.utils_response import APIResponse 	class CoreView(APIView):def get(self, request, *args, **kwargs):# return APIResponse(name="shazi",password='123123132',token='asdas.da.dasd')# return APIResponse(results=[{"user":'132'},{"hobby":['music','running']}])return APIResponse(headers={"hobby":['music','running']})
  • 在HomeView.vue

<template><div class="home"><h1>首页</h1><!-- 在这里你可以添加一些内容来显示获取到的数据 --><div v-if="dataFromServer"><!-- 使用 dataFromServer 的数据来渲染内容 --><!-- 假设返回的数据是一个对象,并且你想显示其某个属性,例如 message --><p>{{ dataFromServer.message }}</p></div></div>
</template><script setup>
import { reactive, onMounted } from 'vue';
import axios from 'axios';// 使用 reactive 来创建响应式的数据对象
const res = reactive({message: ''
});// 在 onMounted 生命周期钩子中发送请求
onMounted(async () => {try {const response = await axios.get('http://127.0.0.1:8000/user/option/', {headers: {// token: 'asd.fas.sadas' // 在请求头中添加自定义的 token}});res.message = response.data.message;// 这里可以处理响应的其他数据console.log(response);} catch (error) {console.error('Error fetching data:', error);// 在这里你可以选择以某种方式通知用户或处理错误}
});
</script><style scoped>
/* 你的样式代码 */
</style>

image-20240511172929754

  • 解决方法

from rest_framework.views import APIView
from lufy.utils.utils_response import APIResponse 
class CoreView(APIView):def get(self, request, *args, **kwargs):# # return APIResponse(headers={"hobby":['music','running']})# No 'Access-Control-Allow-Origin' header is present on the requested resource.return APIResponse(headers={"Access-Control-Allow-Origin": '*'})

image-20240511175030361

  • Access-Control-Allow-Headers

  • 用于告知浏览器在跨域请求中,所允许的请求头字段

  • urls.py

from django.urls import path
from . import views
from .views import LoggerView, ExceptionView,ResponseView,CoreView,core_viewurlpatterns = [# 日志path('logg/', LoggerView.as_view(), name='home'),# 异常path('except/', ExceptionView.as_view()),# 响应方法path('ponse/', ResponseView.as_view()),# 跨域path('core/', CoreView.as_view()),path('option/', core_view),]
  • views.py

from rest_framework.views import APIView
from lufy.utils.utils_response import APIResponse def core_view(request):res = HttpResponse("ok")res['Access-Control-Allow-Origin'] = '*'if request.method =='OPTIONS':res['Access-Control-Allow-Headers'] = '*'return res

image-20240511191016929

  • 我现在要使用别的请求方法比如put、delete

<script setup>
import { reactive, onMounted } from 'vue';
import axios from 'axios';// 使用 reactive 来创建响应式的数据对象
const res = reactive({message: ''
});// 在 onMounted 生命周期钩子中发送请求
onMounted(async () => {try {const response = await axios.put('http://127.0.0.1:8000/user/option/', {headers: {token: 'asd.fas.sadas' // 在请求头中添加自定义的 token}});res.message = response.data.message;// 这里可以处理响应的其他数据console.log(response);} catch (error) {console.error('Error fetching data:', error);// 在这里你可以选择以某种方式通知用户或处理错误}
});
</script>

image-20240511191419095

  • 我们只需要添加Access-Control-Allow-Methods

  • res['Access-Control-Allow-Headers'] = '*'
    
def core_view(request):res = HttpResponse("ok")res['Access-Control-Allow-Origin'] = '*'if request.method =='OPTIONS':res['Access-Control-Allow-Headers'] = '*'res['Access-Control-Allow-Methods'] = '*'return res
# 注意注释跨域403
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]

image-20240511192131238

image-20240511192156561

​ 非简单请求(non-simple requests)在CORS(跨源资源共享)中,指的是不满足简单请求条件的请求。简单请求和非简单请求的区分主要是基于HTTP请求的一些特性,而不仅仅是基于发送了几次请求。

简单请求需要满足以下条件:

  1. 请求方法只能是以下几种之一:HEAD、GET、POST。
  2. HTTP头信息不超出以下几种字段:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限于三个值 application/x-www-form-urlencodedmultipart/form-datatext/plain

​ 如果HTTP请求不满足以上条件,那么它就是一个非简单请求。

​ 非简单请求在浏览器发送真正的请求之前,会首先发送一个预检请求(preflight request),请求方法是OPTIONS。预检请求会询问服务器是否允许该跨域请求。服务器响应预检请求时,需要包含一些CORS相关的响应头信息,比如 Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers 等,来告知浏览器该跨域请求是否被允许。

​ 所以,非简单请求并不是看你发送了几次请求,而是看请求的HTTP方法、头信息等是否满足简单请求的条件。如果不满足,浏览器就会发送预检请求,这增加了一次额外的HTTP请求。

【 2 】自定义中间件

  • views.py

from rest_framework.views import APIView
from lufy.utils.utils_response import APIResponse 
def core_view(request):res = HttpResponse("ok")return res
  • urls.py

from django.urls import path
from . import views
from .views import core_viewurlpatterns = [# optionpath('option/', core_view),]
  • 在utils/utils.
## 中间件###
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):def process_response(self,request,response):if request.method=="OPTIONS":#可以加*response["Access-Control-Allow-Headers"]="*"response['Access-Control-Allow-Methods'] = '*'response["Access-Control-Allow-Origin"] = "*"return response
  • 配置文件新的dev.py

MIDDLEWARE = ['utils.utils_middleware.CorsMiddleWare',
]
<template><div class="home"><h1>首页</h1><!-- 在这里你可以添加一些内容来显示获取到的数据 --><!-- 使用 dataFromServer 的数据来渲染内容 --><!-- 假设返回的数据是一个对象,并且你想显示其某个属性,例如 message --><p>{{ res.message }}</p></div></template><script setup>
import { reactive, onMounted } from 'vue';
import axios from 'axios';// 使用 reactive 来创建响应式的数据对象
const res = reactive({message: ''
});// 在 onMounted 生命周期钩子中发送请求
onMounted(async () => {try {const response = await axios.put('http://127.0.0.1:8000/user/option/', {headers: {token: 'asd.fas.sadas' // 在请求头中添加自定义的 token}});res.message = response.data.message;// 这里可以处理响应的其他数据console.log(response);} catch (error) {console.error('Error fetching data:', error);// 在这里你可以选择以某种方式通知用户或处理错误}
});
</script><style scoped>
/* 你的样式代码 */
</style>

image-20240511193557916

【 3 】第三方app解决

# 1、使用pip安装
pip install django-cors-headers# 2、添加到setting的app中
INSTALLED_APPS = (...'corsheaders',...
)
# 3、添加中间件
MIDDLEWARE = [  ...'corsheaders.middleware.CorsMiddleware',...
]
# 4、setting下面添加下面的配置
CORS_ORIGIN_ALLOW_ALL = True
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','token',
)### 中间件源码分析
if conf.CORS_ALLOW_ALL_ORIGINS and not conf.CORS_ALLOW_CREDENTIALS:response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*"
if request.method == "OPTIONS":response[ACCESS_CONTROL_ALLOW_HEADERS] = ", ".join(conf.CORS_ALLOW_HEADERS)response[ACCESS_CONTROL_ALLOW_METHODS] = ", ".join(conf.CORS_ALLOW_METHODS)
  • 1、使用pip安装

    # pip install django-cors-headers
    

    image-20240511193807957

  • 2、添加到setting的app中

INSTALLED_APPS = (...'corsheaders',...)
  • 3、添加中间件

    MIDDLEWARE = [  ...'corsheaders.middleware.CorsMiddleware',...
    ]
    
  • 4、setting下面添加下面的配置(放在新建的common_settings)

    CORS_ORIGIN_ALLOW_ALL = True
    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','token',
    )
    

    image-20240511194116226

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【区分vue2和vue3下的element UI Carousel 走马灯组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Vue 2 中&#xff0c;我们通常使用 Element UI&#xff0c;而在 Vue 3 中&#xff0c;我们则使用 Element Plus 作为其替代品。对于 Carousel 走马灯组件&#xff0c;这两个库提供了相似的功能&#xff0c;但在 Vue 2 和 Vue 3 的上下文中&#xff0c;它们的属性、事件和方法…

C\C++ 终端输出带有颜色的字符

终端显示带有颜色的字符 终端显示带有颜色的字符 终端显示带有颜色的字符背景&#xff1a;测试机器&#xff0c;win10系统&#xff0c; VS2022编写字体设置不同的颜色背景色光标移动 &#xff08;这个用的估计不是很多&#xff09;字体设置动态显示C cout 也可以测试代码准确的…

接口基础知识3:详解url

课程大纲 一、定义 URL即访问的链接&#xff0c;是Uniform Resource Locator的缩写&#xff0c;译为"统一资源定位符"。 URL是一种URI&#xff0c;它标识一个互联网资源&#xff0c;并指定对其进行操作或获取该资源的方法。可能通过对主要访问手段的描述&#xff0c…

SpringBoot详细解析

1.什么是springboot springboot也是spring公司开发的一款框架。为了简化spring项目的初始化搭建的。那么spring对应springboot有什么缺点呢&#xff1f; spring项目搭建的缺点: 配置麻烦依赖tomcat启动慢 2.springboot的特点 自动配置 Spring Boot的自动配置是一个运行时&…

Docker 安装ros 使用rviz 等等图形化程序

Docker 安装ros 使用rviz 等等图形化程序 ubuntu 版本与ros 发行版本对应 如何安装其它版本ros 此时考虑使用docker 易于维护 地址&#xff1a; https://hub.docker.com/r/osrf/ros 我主机是 ubuntu22.04 使用这个标签 melodic-desktop-full 1 clone 镜像到本机 docker pu…

Android OkHttp3中HttpLoggingInterceptor使用

目录 一 概述1.1 日志级别 二 使用2.1 引入依赖2.2 创建对象2.3 添加拦截器 三 结果展示3.1 日志级别为BODY3.2 日志级别为BASIC3.3 日志级别为HEADERS 参考 一 概述 HttpLoggingInterceptor是OkHttp3提供的拦截器&#xff0c;用来记录HTTP请求和响应的详细信息。 1.1 日志级…

基于IDEA的Lombok插件安装及简单使用

lombok介绍 Lombok能以注解形式来简化java代码&#xff0c;提高开发效率。开发中经常需要写的javabean&#xff0c;都需要花时间去添加相应的getter/setter&#xff0c;也许还要去写构造器、equals等方法&#xff0c;而且需要维护。而Lombok能通过注解的方式&#xff0c;在编译…

Spring AOP 实现 Excel 导出统一处理

你好&#xff0c;我是柳岸花开。在实际开发中&#xff0c;经常会遇到需要导出 Excel 数据的需求。为了避免代码重复&#xff0c;我们可以使用 Spring AOP&#xff08;面向切面编程&#xff09;来实现 Excel 导出的统一处理。本文将介绍如何使用 Spring AOP 在项目中统一处理 Ex…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十三)-更换无人机控制器

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

枚举的高阶用法之枚举里写方法以及注入spring的bean

1、前言 一般我们使用枚举都是用来定义一些常量。比如我们需要一个表示订单类(pc订单、手机订单)的常量,那我们就可以使用枚举来实现,如下: AllArgsConstructor public enum OrderTypeEnum{PC("PC", "电脑端"),PHONE("PHONE", "手机端&quo…

[计网初识2]web的3个核心标准html,url,http

学习内容 HTML,URL,HTTP的构成 1.规范web的3个核心标准&#xff1f; HTML(Hyper Text Markup Language),规范网页内容和版面布局的表示标准。URL(Uniform Resource Locator)&#xff0c;规范网页识别符格式和含义的表示标准。HTTP(HyperText Transfer Protocl),规范游览器如…

JIRA的高级搜索JIRA Query Language(JQL)详解

JIRA的高级搜索功能非常强大&#xff0c;允许用户通过JIRA Query Language&#xff08;JQL&#xff09;来构建复杂的查询。以下是一些常用的高级搜索用法和示例&#xff1a; 1. 基本语法 JQL的基本语法包括字段、运算符和值的组合。例如&#xff1a; field operator value2.…

<数据集>UA-DETRAC车辆识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;20500张 标注数量(xml文件个数)&#xff1a;20500 标注数量(txt文件个数)&#xff1a;20500 标注类别数&#xff1a;4 标注类别名称&#xff1a;[car, van, others, bus] 序号类别名称图片数框数1car201871259342…

钡铼ARMxy控制器在智能网关中的应用

随着IoT物联网技术的飞速发展&#xff0c;智能网关作为连接感知层与网络层的枢纽&#xff0c;可以实现感知网络和通信网络以及不同类型感知网络之间的协议转换。钡铼技术的ARMxy系列控制器凭借其高性能、低功耗和高度灵活性的特点&#xff0c;在智能网关中发挥了关键作用&#…

数据结构回顾(Java)

1.数组 线性表 定义的方式 int[] anew int[10] 为什么查询快&#xff1f; 1.可以借助O(1)时间复杂度访问某一元素&#xff0c; 2.地址连续&#xff0c;逻辑连续 3.数组长度一旦确定就不可以被修改 当需要扩容的时候需要将老数组的内容复制过来 在Java中数组是一个对象 Ar…

bug定位策略

前提--用户环境层面 hosts异常&#xff1a;hosts文件主要是加快某个域名或者网站的解析速度&#xff0c;从而达到快速访问的作用&#xff0c;也可以屏蔽网站。hosts异常可能会导致部分网页无法访问&#xff0c;能够加载&#xff0c;但是网页无法正常显示&#xff1b;测试环境脏…

记录些Redis题集(2)

Redis 的多路IO复用 多路I/O复用是一种同时监听多个文件描述符&#xff08;如Socket&#xff09;的状态变化&#xff0c;并能在某个文件描述符就绪时执行相应操作的技术。在Redis中&#xff0c;多路I/O复用技术主要用于处理客户端的连接请求和读写操作&#xff0c;以实现高并发…

Python_使用pyecharts构建折线图

Pyecharts简介 Pyecharts是一款将python与echarts结合的强大的数据可视化工具&#xff0c;使用 pyecharts 可以生成独立的网页&#xff0c;也可以在 flask , Django 中集成使用。echarts &#xff1a;百度开源的一个数据可视化 JS 库&#xff0c;主要用于数据可视化。pyechart…

嵌入式linux相机 框图

摄像头读取数据显示到LCD流程 重点&#xff1a;摄像头数据&#xff08;yuyv&#xff0c;mjpeg&#xff0c;rgb&#xff09;&#xff08;640,320&#xff09;与LCD显示数据&#xff08;RGB&#xff09;&#xff08;480&#xff0c;240&#xff09;不同&#xff1b;需要转换&…

ReactRouter v6升级的步骤

React Router v6 引入了一个 Routes 组件&#xff0c;它有点像 Switch &#xff0c;但功能要强大得多。与 Switch 相比&#xff0c; Routes 的主要优势在于&#xff1a; <Routes> 中的所有 <Route> 和 <Link> 都是相对的。这导致在 <Route path> 和 &…