【玩转全栈】—— 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 JsonResponse

def get_csrf_token(request):
    token = get_token(request)
    return JsonResponse({'csrfToken': token})

然后在 urlpatterns 中注册该视图:

from django.urls import path
from . import views

urlpatterns = [
    ...
    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.youkuaiyun.com/download/2403_83182682/90578132

感谢您的观看!!!

### 实现Django后端Vue.js前端集成 #### 创建Django RESTful API 为了使Django能够Vue.js良好协作,通常会采用RESTful风格的API接口来传递JSON格式的数据。这可以通过安装`django-rest-framework`包轻松完成。 ```bash pip install djangorestframework ``` 接着,在Django项目的`settings.py`文件中注册该应用程序并添加必要的中间件[^1]: ```python INSTALLED_APPS = [ ... &#39;rest_framework&#39;, ] MIDDLEWARE = [ ... &#39;corsheaders.middleware.CorsMiddleware&#39;, # 如果需要跨域资源共享(CORS),则需额外安装&#39;django-cors-headers&#39; ] ``` 对于模型定义以及序列化器编写,则依据具体的应用场景而定。这里假设有一个简单的用户资料管理案例,其中涉及到了用户的创建、读取、更新和删除(CRUD)操作[^2]。 #### 设置CORS策略 由于Vue应用可能运行于不同的服务器上,因此有必要配置允许跨源资源分享(Cross-Origin Resource Sharing, CORS)。为此可以在`settings.py`里加入如下设置以开放特定域名访问权限或是完放开(仅限开发测试阶段),防止浏览器同源政策阻止请求发出[^3]: ```python from corsheaders.defaults import default_headers CORS_ALLOW_ALL_ORIGINS = True # 不建议生产环境中这样做;应指定确切的信任来源列表 # 或者更安的方式是指定信任的具体URL模式: # CORS_ALLOWED_ORIGINS = [&#39;http://localhost:8080&#39;] ``` #### 构建Vue前端工程并之对接 借助CLI工具快速初始化一个新的Vue项目,并按照官方文档指导安装axios库以便发起HTTP调用[^4]: ```bash npm init vue@latest my-vue-app cd my-vue-app npm install axios --save ``` 随后修改`src/main.js`或者其他合适位置引入Axios实例对象,调整baseURL指向本地正在监听的服务地址如`http://127.0.0.1:8000/api/`,确保路径匹配到已有的视图函数或类视图方法所对应的路由规则下。 最后一步就是根据实际业务逻辑编码相应的页面组件,比如展示用户列表、详情页表单等,利用v-model指令绑定输入框值变化事件至状态变量,再经由methods属性下的异步回调函数触发网络请求获取最新数据刷新DOM节点显示内容。 ```javascript // 示例:在某个.vue 文件内的<script setup>标签内 import { ref } from &#39;vue&#39;; import axiosInstance from &#39;./api&#39;; // 自定义封装好的axios实例 const users = ref([]); async function fetchUsers() { try { const response = await axiosInstance.get(&#39;/users/&#39;); users.value = response.data; } catch (error) { console.error(error); } } fetchUsers(); ``` 这样就完成了基本的功能模块搭建工作,当然这只是冰山一角,随着项目规模扩大还会涉及到更多复杂的技术细节处理,例如身份验证机制设计、错误提示友好化改进等方面的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值