【玩转全栈】—— Django 连接 vue3 保姆级教程,前后端分离式项目2025年4月最新!!!

本文基于之前的一个旅游网站,实现 Django 连接 vue3,使 vue3 能携带 CSRF Token 发送 axios 请求给后端,后端再响应数据给前端。想要源码直接滑倒底部。

目录

实现效果

解决跨域

获取 csrf-token

什么是  csrf-token ?

CSRF攻击的工作原理

CSRF Token的作用

在前后端分离项目中的应用

问题

解决方案

Django 获取 CSRF Token

前端获取

 配置 Vite 代理

下载 axios

请求 CSRF Token

运行前后端项目

请求与相应

请求

响应

后端返回数据

前端接收数据

源码获取


实现效果

Django5连接前端vue3,前后端分离式项目(Django+vue3+csrf-token+axios)

解决跨域

下载解决跨域的包:

pip install django-cors-headers

注册,并配置中间件

INSTALLED_APPS = ["corsheaders",
]
MIDDLEWARE.insert(0, 'corsheaders.middleware.CorsMiddleware')

允许其他端口来源(仅用于开发环境)

CORS_ALLOW_ALL_ORIGINS = True

获取 csrf-token

什么是  csrf-token 

        Django中的CSRF Token(Cross-Site Request Forgery Token,跨站请求伪造令牌)主要用于防止CSRF攻击。这是一种针对网站的恶意攻击模式,攻击者通过伪装来自受信任用户的请求来利用已认证的用户数据进行非法操作。

CSRF攻击的工作原理

        假设你登录了一个银行网站,并且在没有登出的情况下访问了一个恶意网站。如果该银行网站对某些敏感操作(如转账)的安全措施不足,恶意网站可以通过自动提交表单或发送AJAX请求的方式,利用你的身份和已登录状态向银行网站发起转账请求。由于请求是从你的浏览器发出的,同时包含有效的会话Cookie,银行服务器无法区分这个请求是合法的还是伪造的,从而可能导致资金被非法转移。

CSRF Token的作用

为了防止上述情况发生,Django使用CSRF Token作为额外的安全层。具体工作流程如下:

  1. 生成Token:当用户访问一个包含表单的页面时,Django会在响应中设置一个名为csrftoken的Cookie,并且在HTML表单中插入一个隐藏字段,其值为相同的CSRF Token。

  2. 验证Token:当用户提交表单时,无论是通过POST请求还是其他非安全方法(如PUT、DELETE等),Django都会检查请求中的CSRF Token是否与存储在Cookie中的Token相匹配。只有当两者匹配时,才会处理该请求;否则,请求将被拒绝并返回403 Forbidden错误。

  3. 安全性保障:这种方法有效地阻止了第三方网站直接构造请求并利用已登录用户的会话信息执行未授权操作的可能性,因为它们无法获取到正确的CSRF Token。

在前后端分离项目中的应用

        在传统的Django项目中,模板渲染机制使得CSRF Token很容易集成进每个需要保护的表单或AJAX请求中。然而,在前后端分离的应用场景下,前端可能是一个独立运行的Vue.js、React或其他JavaScript框架开发的应用,这种情况下,获取和使用CSRF Token需要一些额外的工作,比如通过特定的API接口获取Token,并确保每次请求都正确地包含了这个Token。这通常涉及到在前端代码中添加逻辑来获取和附加CSRF Token到请求头中。

问题

Django 默认启用了 CSRF 保护机制,要求所有非安全 HTTP 方法(如 POSTPUTDELETE)必须包含有效的 CSRF Token。如果前端未正确获取或发送 CSRF Token,就会触发以下错误:

CSRF verification failed. Request aborted.
CSRF cookie not set.

在传统的 Django 项目中,CSRF Token 通常是通过模板渲染(如 {% csrf_token %})或默认机制生成的,并存储在 Cookie 中,其中,{% csrf_token %}在我之前的所有 Django 教程中都在html页面中编写了然而,在前后端分离的架构中:

  • 前端和后端是独立运行的。
  • 前端可能不会直接加载 Django 提供的页面,因此无法自动获取 CSRF Token。

 

解决方案

Django 获取 CSRF Token

Django 提供了一个专门的视图  /csrf/ ,可以用来手动获取 CSRF Token。你可以通过以下步骤实现:

配置 Django 视图

在 Django 的 urls.py 文件中添加一个视图来返回 CSRF Token

from django.middleware.csrf import get_token
from django.http import JsonResponsedef get_csrf_token(request):token = get_token(request)return JsonResponse({'csrfToken': token})

然后在 urlpatterns 中注册该视图:

from django.urls import path
from . import viewsurlpatterns = [...path('csrf/', views.get_csrf_token, name='get_csrf_token'),
]

前端获取

 配置 Vite 代理

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';export default defineConfig({server: {proxy: {'/api': {target: 'http://127.0.0.1:8080', // 确保与 Django 后端地址一致changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, ''),secure: false, // 如果后端使用 HTTPS,可能需要设置为 true},},},resolve: {alias: {'@': path.resolve(__dirname, 'src'),},},plugins: [vue()],
});

下载 axios

npm install axios 

请求 CSRF Token

import axios from 'axios';let csrfToken = null;// 获取 CSRF Token
async function fetchCsrfToken() {try {const response = await axios.get('/api/csrf/');csrfToken = response.data.csrfToken;console.log("CSRF Token:", csrfToken);} catch (error) {console.error("Error fetching CSRF token:", error.response?.data || error.message);}
}fetchCsrfToken()

运行前后端项目

# 运行后端
python manage.py runserver 8080// 运行前端
npm run dev

后端处理请求:

前端获取到 token:

有了 token 之后,前端的一系列数据就能被后端安全接收,像用户管理之类的功能就能安全得进行了。

请求与相应

前端如何发送请求给 DjangoDjango 又如何相应数据给前端?

请求

前面讲的 前端获取 csrf-token 其实就是响应。配置 Vite 代理后,再使用 axios 发送请求给 Django:

这里我再给个示例:

前端通过 /api/ask 发送请求,携带 CSRF Token 请求头,将用户输入的 question json 形式发POST Django :

async function sendQuestion() {if (!csrfToken) {console.error("CSRF Token is not available");return;}try {const response = await axios.post('/api/ask/', { question: question.value }, {headers: {'X-CSRFToken': csrfToken, // 添加 CSRF Token 到请求头'Content-Type': 'application/json', // 指定内容类型为 JSON},});console.log("Response from Django:", response.data);} catch (error) {console.error("Error sending question:", error.response?.data || error.message);}
}

后端定义 url:

path('ask/', views.ai_talk, name='ai_talk'),  # 使用类视图

视图函数接收前端的 POST 数据并解析:

def ai_talk(request):if request.method == 'POST':try:# 从请求体中获取 JSON 数据body = request.body.decode('utf-8')  # 将字节流解码为字符串data = json.loads(body)  # 将 JSON 字符串解析为 Python 字典# 获取用户输入的问题user_question = data.get('question', '').strip()print(f"用户输入的问题: {user_question}")except Exception as e:# 处理异常print(f"解析请求数据失败: {e}")return HttpResponse("请求数据无效", status=400)else:# 如果不是 POST 请求,返回错误return HttpResponse("仅支持 POST 请求", status=405)

得到数据:

响应

后端返回数据

Django 已经接收到了数据,可以通过 HttpResponse 或  JsonResponse 将数据返回,这里使用JsonResponse 以 json格式返回数据,仅需在视图函数中加入返回代码:

# 返回 JSON 响应
return JsonResponse({'status': 'success','message': ai_response,
})

前端接收数据

定义一个列表接收返回数据

const aiResponse = ref<string[]>([]); // 响应数据列表

在前端发送问题的同时,请求后端的响应:

// 发送问题到后端
async function sendQuestion() {if (!csrfToken) {console.error("CSRF Token is not available");return;}try {const response = await axios.post('/api/ask/', { question: question.value }, {headers: {'X-CSRFToken': csrfToken, // 添加 CSRF Token 到请求头'Content-Type': 'application/json', // 指定内容类型为 JSON},});// 获取后端返回的数据const responseData = response.data;console.log("Response from Django:", responseData);if (responseData.status === 'success') {//添加数据到相应列表aiResponse.value.push(responseData.message);} else {console.error("Error from backend:", responseData.message);}// 清空问题输入框question.value = '';} catch (error) {console.error("Error sending question:", error.response?.data || error.message);}
}

再显示到页面上。

源码获取

上面是 Django 代码,下面是 vue3 代码。

资源地址:https://download.csdn.net/download/2403_83182682/90578132

感谢您的观看!!!

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

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

相关文章

dify部署,ollama部署,拉取模型,创建ai聊天应用

dify下载安装 dify1.0.1 windos安装包百度云盘地址 通过网盘分享的文件&#xff1a;dify-1.0.1.zip 链接: 百度网盘 请输入提取码 提取码: 1234 dify安装包 linux安装包百度云盘地址 通过网盘分享的文件&#xff1a;dify-1.0.1.tar.gz 链接: 百度网盘 请输入提取码 提取码…

docx文档转为pdf文件响应前端

1、转换文件&#xff08;docx~pdf&#xff09; 1.引入pom依赖 <dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>20.12.0</version> </dependency>2.读取docx文档数据-转换 // 初…

网络安全中信息收集需要收集哪些信息了?汇总

目录 1. 域名信息 2. IP地址与网络信息 3. 备案与注册信息 4. Web应用与中间件信息 5. 操作系统与服务器信息 6. 敏感文件与配置文件 7. 社交工程信息 8. 证书与加密信息 9. API与接口信息 10. 外部威胁情报 11. 历史数据与缓存 常用工具与技术&#xff1a; 在网络…

【锂电池SOH预测】PSO-BP锂电池健康状态预测,锂电池SOH预测(Matlab完整源码和数据)

预测效果 基于PSO-BP算法的锂电池健康状态预测研究 一、引言 1.1 研究背景与意义 在当今社会&#xff0c;锂电池凭借其高能量密度、长寿命及环境友好等特性&#xff0c;在现代能源系统中占据着举足轻重的地位。从消费电子领域如智能手机、笔记本电脑&#xff0c;到动力领域中…

智能车摄像头开源—9 动态权、模糊PID、速度决策、路径优化

目录 一、前言 二、动态权 1.概述 2.偏差值加动态权 三、模糊PID 四、速度决策 1.曲率计算 2.速度拟合 3.速度控制 五、路径 六、国赛视频 一、前言 在前中期通过识别直道、弯道等元素可进行加减速操作实现速度的控制&#xff0c;可进一步缩减一圈的运行速度&#xff…

过往记录系列 篇五:市场黑天鹅事件历史梳理

文章目录 系列文章文章地址文章摘要文章预览系列文章 过往记录系列 篇一:牛市板块轮动顺序梳理 过往记录系列 篇二:新年1月份(至春节前)行情历史梳理 过往记录系列 篇三:春节行情历史梳理 过往记录系列 篇四:年报月行情历史梳理 文章地址 原文审核不通过(理由:“违反…

Mysql--基础知识点--85.1--Innodb自适应哈希索引

1. 自适应哈希索引的用途 InnoDB 的自适应哈希索引&#xff08;Adaptive Hash Index, AHI&#xff09;是 MySQL 数据库引擎中一项智能优化查询性能的功能。其核心作用如下&#xff1a; 加速等值查询 哈希索引通过哈希函数将键映射到固定位置&#xff0c;实现 O(1) 时间复杂度的…

SQL优化技术分享:从 321 秒到 0.2 秒的性能飞跃 —— 基于 PawSQL 的 TPCH 查询优化实战

在数据库性能优化领域&#xff0c;TPC-H 测试集是一个经典的基准测试工具&#xff0c;常用于评估数据库系统的查询性能。本文将基于 TPCH 测试集中的第 20个查询&#xff0c;结合 PawSQL 自动化优化工具&#xff0c;详细分析如何通过 SQL 重写和索引设计&#xff0c;将查询性能…

SpringBoot3-web开发笔记(下)

内容协商 实现&#xff1a;一套系统适配多端数据返回 多端内容适配&#xff1a; 1. 默认规则 SpringBoot 多端内容适配。 基于请求头内容协商&#xff1a;&#xff08;默认开启&#xff09; 客户端向服务端发送请求&#xff0c;携带HTTP标准的Accept请求头。 Accept: applica…

Graylog 索引配置详解与优化建议

Graylog 索引配置详解与优化建议 &#x1f680; 前言一、索引集基础信息 &#x1f4da;二、分片&#xff08;Shards&#xff09;与副本&#xff08;Replicas&#xff09;设置 ⚙️1. 分片 (Shards)2. 副本 (Replicas) 三、 字段类型刷新间隔&#xff08;Field Type Refresh Int…

数据结构*包装类泛型

包装类 什么是包装类 在讲基本数据类型的时候&#xff0c;有提到过包装类。 基本数据类型包装类byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean 我们知道&#xff1a;基本数据类型并不是对象&#xff0c;没有对象所具有的方法和属…

【JDBC-54.1】MySQL JDBC连接字符串常用参数详解

在Java应用程序中连接MySQL数据库时&#xff0c;JDBC连接字符串是建立连接的关键。一个配置得当的连接字符串不仅能确保连接成功&#xff0c;还能优化性能、增强安全性并处理各种连接场景。本文将深入探讨MySQL JDBC连接字符串的常用参数及其最佳实践。 1. 基本连接字符串格式…

[ctfshow web入门] web37

信息收集 题目有了变化&#xff0c;include$c if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag/i", $c)){include($c);echo $flag;}}else{highlight_file(__FILE__); }解题 通过协议解题 参考[ctfshow web入门] web31 同样是include&#xff0c;之前的方…

Linux 调试代码工具:gdb

文章目录 一、debug vs release&#xff1a;两种程序形态的本质差异1. 什么是 debug 与 release&#xff1f;2. 核心差异对比 二、为什么需要 debug&#xff1a;从项目生命周期看调试价值1. 项目开发流程中的调试闭环&#xff08;流程图示意&#xff09;2. Debug 的核心意义与目…

Python设计模式:命令模式

1. 什么是命令模式&#xff1f; 命令模式是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使您能够使用不同的请求、队列或日志请求&#xff0c;以及支持可撤销操作。 命令模式的核心思想是将请求的发送者与请求的接收者解耦&#xff0c;使得两者之间的…

nlp面试重点

深度学习基本原理&#xff1a;梯度下降公式&#xff0c;将损失函数越来越小&#xff0c;最终预测值和实际值误差比较小。 交叉熵&#xff1a;-p(x)logq(x)&#xff0c;p(x)是one-hot形式。如果不使用softmax计算交叉熵&#xff0c;是不行的。损失函数可能会非常大&#xff0c;…

Leetcode:二叉树

94. 二叉树的中序遍历 class Solution {public List<Integer> inorderTraversal(TreeNode root) {TreeNode cur root;Stack<TreeNode> stack new Stack<>();List<Integer> list new ArrayList<>();while (!stack.isEmpty() || cur ! null) {…

SQL:Constraint(约束)

目录 &#x1f3af; 什么是 Constraint&#xff1f; MySQL 中常见的约束类型&#xff1a; 1. PRIMARY KEY 2. FOREIGN KEY 3. UNIQUE 4. NOT NULL 5. DEFAULT 6. CHECK&#xff08;MySQL 8.0&#xff09; 7. AUTO_INCREMENT &#x1f3af; 什么是 Constraint&#xf…

数据库数据恢复——sql server数据库被加密怎么恢复数据?

SQL server数据库数据故障&#xff1a; SQL server数据库被加密&#xff0c;无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密&#xff0c;文件名字被篡改。 SQL server数据库数据恢复过程&#xff1a; 1、将所有数据库做完整只读备份。后续所有数据恢…

MySQL 用 limit 影响性能的优化方案

一.使用索引覆盖扫描 如果我们只需要查询部分字段&#xff0c;而不是所有字段&#xff0c;我们可以尝试使用索引覆盖扫描&#xff0c;也就是让查询所需的所有字段都在索引中&#xff0c;这样就不需要再访问数据页&#xff0c;减少了随机 I/O 操作。 例如&#xff0c;如果我们…