JavaScript fetch请求Django接口时出现JSON解析SyntaxError报错
Django + JS 表单提交接口触发JSON解析错误排查
问题场景
开发表单创建功能时,交互逻辑为:点击「创建空白表单」按钮后向后端发送POST请求,预期接口返回JSON格式响应,拿到表单唯一编码后跳转到对应表单的编辑页面。实际运行时前端抛出JSON解析错误,无法完成跳转。
报错信息
浏览器控制台抛出如下错误:
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 Promise.then (async) (anonymous)
该错误指向前端处理接口响应的.then(result => ...)逻辑段。
关联代码
前端 index.js
document.querySelector("#create-blank-form").addEventListener("click", () => { const csrf = Cookies.get('csrftoken'); fetch('/form/create', { method: "POST", headers: {'X-CSRFToken': csrf}, body: JSON.stringify({ title: "Untitled Form" }) }) .then(response => response.json()) .then(result => { window.location = `/form/${result.code}/edit` }) })
后端 views.py
def create_form(request): print('hi') # 校验创建者登录状态 # 空白表单创建接口 if request.method == "POST": print('hi') data = json.loads(request.body) title = data["title"] code = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(30)) choices = Choices(choice = "Option 1") choices.save() question = Questions(question_type = "multiple choice", question= "Untitled Question", required= False) question.save() question.choices.add(choices) question.save() form = Form(code = code, title = title, creator=request.user) form.save() form.questions.add(question) form.save() return JsonResponse({"message": "Sucess", "code": code})
前端HTML模板片段
<div class="form-template-box"> <img src = "{% static 'Icon/blank-form.png' %}" alt = "Blank form" title = "Blank form" id="create-blank-form"> <span class="form-template-label">Blank Form</span> </div>
路由urls.py配置片段
path('form/create', views.create_form, name="create_form"),
问题根因
路由配置存在冲突:urls.py中其他同前缀路由规则抢先匹配了/form/create请求,导致请求没有进入预期的create_form视图函数,接口实际返回的是HTML格式内容(多为Django默认404页面、登录重定向页面或其他匹配路由返回的HTML页)。前端未校验响应类型直接调用response.json()解析时,HTML内容的首字符通常为<,不符合JSON语法规范,直接触发解析错误。
修复方案
- 调整路由匹配顺序:Django路由按照从上到下的顺序匹配,命中第一条规则后就会停止向后匹配,需要将精确匹配的
form/create路由放到同前缀的动态路由(比如form/<str:code>/edit这类带路径参数的规则)之前,避免动态路由抢先拦截请求 - 调试阶段可打开浏览器开发者工具,在Network面板找到
/form/create请求,查看实际响应内容,快速定位是哪条路由错误匹配了请求 - 前端可增加响应类型校验逻辑,不要直接调用
response.json(),先判断响应头的content-type是否包含application/json,解析失败时给出明确的错误提示,降低排查成本
内容的提问来源于stack exchange,提问作者Rod
相关产品推荐
相关产品推荐

