提交AJAX表单至Express API时遇JSON解析错误:Unexpected token #
我来帮你排查这个问题,这个错误本质是前端尝试解析非合法JSON格式的响应内容,而根源出在前端请求数据的格式和后端的解析配置不匹配上,一步步来修复:
1. 前端请求数据格式错误
你现在用JSON.stringify($(form).serialize())来生成请求体,但serialize()返回的是类似name=xxx的URL编码字符串,转成JSON后会变成"name=xxx"——这是一个JSON字符串,不是后端期望的JSON对象(比如{"name":"xxx"})。同时你设置了Content-Type: application/json,后端收到这个不符合格式的JSON自然解析失败,进而返回错误内容,前端解析这些错误内容时就会抛出Unexpected token #...的异常。
修复前端代码:把表单数据转换成合法的JSON对象再序列化:
$(document).ready(function() { let form = $("#submitableform"); form.submit(function (event) { event.preventDefault(); // 把表单数据转成JSON对象 let formData = {}; $(form).serializeArray().forEach(item => { formData[item.name] = item.value; }); $.ajax({ type: $(form).attr('method'), url: $(form).attr('action'), dataType: 'json', data: JSON.stringify(formData), // 序列化合法的JSON对象 headers: { 'Content-Type':'application/json' }, success: function (result) { console.log(result); }, error: function (xhr, resp, text) { console.log(xhr, resp, text); } }); }); });
2. 后端body-parser配置问题
你的路由里用了router.use(bodyParser());,这个写法已经被废弃了,而且默认不会启用JSON格式的请求体解析——前端发送的是application/json类型的数据,后端无法解析,导致req.body为undefined,之后控制器返回的字符串"request body : undefined"不是合法JSON,前端解析时就会报错。
修复后端路由配置:明确启用JSON解析:
const express = require('express'); const router = express.Router(); const ListingController = require('./listing_controller'); const bodyParser = require('body-parser'); // 启用JSON格式请求体解析 router.use(bodyParser.json()); // 如果之后需要处理表单编码的请求,也可以加上这个 router.use(bodyParser.urlencoded({ extended: true })); router.post('/listings', (req, res) => { ListingController.createUser(req, res); }); module.exports = router;
3. 控制器响应格式错误
你现在用res.send("request body : " + req.body);返回字符串,但前端期望的是JSON格式的响应,即使要返回请求体信息,也应该返回JSON对象,这样前端才能正确解析。
修复控制器代码:
module.exports = { createUser: (req, res) => { // 返回JSON格式的响应 res.json({ message: "Request received successfully", requestBody: req.body }); } };
做完这三步,再测试表单提交,应该就能正常工作了。
内容的提问来源于stack exchange,提问作者apostrophedottilde

