You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Ajax向带CSRF保护的Django发送JSON POST请求并解析?

解决Django中Ajax发送JSON POST请求(带CSRF保护)的问题

你的问题核心在于JSON格式的POST请求和Django CSRF中间件的兼容,以及后端如何正确解析JSON数据。我帮你一步步梳理正确的实现流程:

一、前端Ajax代码的修正

你原来的写法有两个关键问题:

  1. 把CSRF Token放在了JSON数据里,但Django的CSRF中间件不会从JSON payload中读取csrfmiddlewaretoken字段;
  2. jQuery的$.ajax在设置contentType: "application/json"时,不会自动把对象格式的data转成JSON字符串,导致发送的数据格式不对。

修改后的前端代码如下:

首先,添加一个获取CSRF Token的工具函数(从Django设置的Cookie中读取):

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
const csrftoken = getCookie('csrftoken');

然后调整Ajax请求:

$.ajax({
    type: "POST",
    url: '/change_ref/'+hash+"/",
    // 把CSRF Token放到请求头里,这是Django CSRF中间件认可的方式
    headers: {
        'X-CSRFToken': csrftoken
    },
    // 手动把数据转成JSON字符串
    data: JSON.stringify({"new_ref": newref}),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){
        $('#changeref').modal('hide');
        alert('Success!');
    },
    // 注意jQuery的错误回调是error,不是failure
    error: function(jqXHR, textStatus, errMsg) {
        alert('Failure! ' + errMsg);
    }
});

二、后端视图的正确实现

Django默认的request.POST只处理表单编码的数据(application/x-www-form-urlencoded),对于JSON格式的请求,你需要从request.body中读取原始数据并解析:

import json
from django.http import JsonResponse
from django.views.decorators.http import require_POST

@require_POST  # 只允许POST请求
def change_ref_view(request, hash_value):
    try:
        # 解析JSON数据
        payload = json.loads(request.body)
        new_ref = payload.get('new_ref')
        
        # 这里写你的业务逻辑,比如更新数据库等
        # 示例:假设你有一个模型需要更新
        # obj = YourModel.objects.get(hash=hash_value)
        # obj.ref = new_ref
        # obj.save()
        
        return JsonResponse({'status': 'success', 'message': 'Reference updated'})
    except json.JSONDecodeError:
        # 处理JSON解析失败的情况
        return JsonResponse({'status': 'error', 'message': 'Invalid JSON data'}, status=400)
    except YourModel.DoesNotExist:
        # 处理找不到对象的情况(根据你的业务需求调整)
        return JsonResponse({'status': 'error', 'message': 'Object not found'}, status=404)

三、URL配置的注意事项

确保你的URL路由正确接收hash参数,比如在urls.py中:

from django.urls import path
from . import views

urlpatterns = [
    # 这里的<str:hash_value>对应视图中的hash_value参数
    path('change_ref/<str:hash_value>/', views.change_ref_view, name='change_ref'),
]

关键原理说明

  • Django的CSRF中间件会检查X-CSRFToken请求头(或者Cookie中的csrftoken),所以发送JSON请求时必须在请求头中携带这个Token;
  • 当请求的Content-Type是application/json时,Django不会自动解析数据到request.POST,必须手动读取request.body并解析为JSON对象。

内容的提问来源于stack exchange,提问作者Alberto Deca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:12:33