向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
相关产品推荐
相关产品推荐

