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

向Django发送JSON对象返回500错误,数据已保存但请求报错

问题描述

我通过AJAX向Django视图发送鼠标移动数据对象,每10秒发送一次用于保存。目前客户端和服务端均可读取数据,数据也能存入数据库,但每次执行发送函数都会返回500错误。尝试使用fetch时,报错信息为:

POST error: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

推测问题出在数据类型,但不确定如何排查修复。以下是相关代码:

客户端JS代码

var target_id = '';
var eventsLog = {"mouse": []};

function logMouse(event){
  target_id = event.target.id;
  currDate = new Date()
  start_time = currDate.getHours() + ':' + currDate.getMinutes() + ':' + currDate.getSeconds() + ':' + currDate.getMilliseconds();

 var insert = [start_time, target_id];
  (eventsLog.mouse).push(insert);
}
var timesPerSecond = 5; 
var wait = false;
$(document).on('mousemove', function (event) {
  if (!wait) {   
      logMouse(event);
      wait = true;
      setTimeout(function () {
          wait = false;
      }, 1000 / timesPerSecond);
  } 
});
const post_url = server_url;
function sendMovement() {
   /* fetch(post_url, {
      method: 'POST',
      body: JSON.stringify(eventsLog),
      credentials: 'include',
      headers: {'Content-Type': 'application/json'}
  }).then(res => res.json()).then(response => {
      console.log('POST response:', response);

  }).catch(error => {
      console.log('POST error:', error);
  });*/

    $.ajax({
        type: "POST",
        url: server_url,
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(eventsLog),
        dataType: "json",
        success: function () {},
        error: function (req, textStatus, errorThrown){
            console.log('Ooops, something happened: ' + textStatus + ' ' +errorThrown)
        }
    });

Django视图代码

movement = json.loads(request.body.decode('utf-8'))

已确认Django接收的数据类型为字典,但请求始终返回500错误,需协助排查修复。


排查与修复步骤

1. 补全Django视图的响应逻辑

你只提供了解析数据的代码,但500错误大概率是视图内部抛出异常,或未返回合法JSON响应。

修复后的视图示例:

import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt  # 临时跳过CSRF验证,生产环境需改用令牌方式
def movement_view(request):
    if request.method == 'POST':
        try:
            # 解析请求体
            movement = json.loads(request.body.decode('utf-8'))
            # 执行你的数据保存逻辑(例如创建模型实例)
            # MouseMovement.objects.create(logs=movement['mouse'])
            # 必须返回JSON格式响应
            return JsonResponse({'status': 'success', 'received': len(movement['mouse'])})
        except Exception as e:
            # 捕获异常并返回错误信息,方便调试
            return JsonResponse({'status': 'error', 'msg': str(e)}, status=400)
    else:
        return JsonResponse({'status': 'error', 'msg': '仅支持POST请求'}, status=405)

2. 处理CSRF令牌验证

Django默认会拦截无CSRF令牌的POST请求,这是常见的500/403错误原因。

给AJAX请求添加CSRF令牌

在JS中添加获取令牌的逻辑,并加入请求头:

// 获取页面CSRF令牌
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: server_url,
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(eventsLog),
    dataType: "json",
    headers: {'X-CSRFToken': csrftoken},  // 添加CSRF令牌
    success: function (res) {
        console.log('保存成功:', res);
        eventsLog.mouse = [];  // 发送后清空日志,避免重复提交
    },
    error: function (req) {
        console.log('响应内容:', req.responseText);  // 打印响应内容,排查是HTML错误页还是JSON错误
    }
});

3. 验证请求URL正确性

如果server_url指向错误的路由,Django会返回404 HTML页面,客户端解析JSON时就会出现Unexpected token '<'错误。直接在浏览器访问server_url,若返回HTML而非JSON,需检查路由配置。

4. 查看Django控制台日志

500错误的具体原因会输出在Django的运行日志中,比如数据库字段不匹配、变量未定义等。查看日志能快速定位问题。

5. 发送后清空日志数组

每次发送成功后清空eventsLog.mouse,避免重复发送历史数据。


内容的提问来源于stack exchange,提问作者London-35

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:45:19