Multer图片上传JSON解析报错,附代码及Postman配置求助
解决Multer图片上传时的JSON解析错误(Unexpected token - in JSON at position 0)
问题描述
我是Node.js新手,最近在用multer模块实现图片上传功能,我的uploadRouter.js代码如下:
const express = require('express'); const mongoose = require('mongoose'); const autheticate = require('../authenticate'); const multer = require('multer') const bodyParser = require('body-parser'); const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'public/images'); }, filename: (req, file, cb) => { cb(null, file.originalname); } }); const imageFileFilter = (req, file, cb) => { if(!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) { return cb(new Error('You can upload only image files!'), false); } cb(null, true); }; const upload = multer({ storage: storage, fileFilter: imageFileFilter}); const uploadRouter=express.Router(); uploadRouter.use(bodyParser.json()); uploadRouter.route('/') .get(autheticate.verifyUser,autheticate.verifyAdmin,(req,res,next)=>{ res.statusCode = 403; res.end('GET operation not supported on /imageUpload'); }) .post(autheticate.verifyUser,autheticate.verifyAdmin,upload.single('imageFile'),(req,res,next)=>{ res.statusCode=200; res.setHeader('Content-Type','application/json'); res.end('End'); }) .put(autheticate.verifyUser,autheticate.verifyAdmin,(req,res,next)=>{ res.statusCode = 403; res.end('PUT operation not supported on /imageUpload'); }) .delete(autheticate.verifyUser,autheticate.verifyAdmin,(req,res,next)=>{ res.statusCode = 403; res.end('DELETE operation not supported on /imageUpload'); }) module.exports = uploadRouter;
我在Postman里把请求体设置成了form-data格式,但请求头里同时包含了Content-Type: application/json和Authentication: bearer [[TOKEN]],上传图片时出现了下面的错误:
<body> <h1>Unexpected token - in JSON at position 0</h1> <h2>400</h2> <pre>SyntaxError: Unexpected token # in JSON at position 0 at JSON.parse (<anonymous>) at createStrictSyntaxError (F:\Cousera\Node\coursera-node-confusion-server\node_modules\body-parser\lib\types\json.js:157:10) at parse (F:\Cousera\Node\coursera-node-confusion-server\node_modules\body-parser\lib\types\json.js:83:15) at F:\Cousera\Node\coursera-node-confusion-server\node_modules\body-parser\lib\read.js:121:18 at invokeCallback (F:\Cousera\Node\coursera-node-confusion-server\node_modules\raw-body\index.js:224:16) at done (F:\Cousera\Node\coursera-node-confusion-server\node_modules\raw-body\index.js:213:7) at IncomingMessage.onEnd (F:\Cousera\Node\coursera-node-confusion-server\node_modules\raw-body\index.js:273:7) at emitNone (events.js:106:13) at IncomingMessage.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1055:12) at _combinedTickCallback (internal/process/next_tick.js:138:11) at process._tickCallback (internal/process/next_tick.js:180:9)</pre> </body> </html>
我搞不懂这个错误是怎么回事,恳请大家帮忙解决!
问题分析与解决方案
别担心,这个问题其实很常见,咱们一步步拆解:
为什么会报错?
你的错误根源有两个:
- 中间件冲突:你给整个
uploadRouter都加了bodyParser.json()中间件,这会让服务器尝试把所有请求的 body 都当作 JSON 来解析。但你上传图片用的是form-data格式,这是多部分表单数据,根本不是 JSON,JSON 解析器自然会报错。 - 请求头设置错误:你在 Postman 里手动设置了
Content-Type: application/json,这相当于告诉服务器“我发的是 JSON 数据”,但实际发的是图片表单,服务器自然懵了——其实 Postman 会自动为form-data请求设置正确的Content-Type: multipart/form-data; boundary=xxx,完全不需要手动加。
怎么修复?
第一步:移除多余的 JSON 解析中间件
打开你的uploadRouter.js,删掉这一行:
uploadRouter.use(bodyParser.json());
如果你的其他接口需要处理 JSON 请求,把bodyParser.json()加到那些对应的路由里就行,别让它影响上传接口。
第二步:修正 Postman 的请求头
在 Postman 里:
- 切换到
Headers标签,找到Content-Type这一项,直接删除它(别手动设置成任何值) - 只保留
Authentication: bearer [[TOKEN]]这一个自定义头就行
第三步:(可选)优化错误提示
为了让上传失败时的提示更清晰,你可以给上传接口加个错误处理逻辑,替换原来的 post 方法:
.post(autheticate.verifyUser, autheticate.verifyAdmin, (req, res, next) => { upload.single('imageFile')(req, res, (err) => { if (err instanceof multer.MulterError) { // 处理multer内置的上传错误(比如文件大小超限) res.status(400).json({ error: err.message }); } else if (err) { // 处理你自定义的文件类型错误 res.status(400).json({ error: err.message }); } else { // 上传成功返回详细信息,比只返回"End"更有用 res.status(200).json({ message: "图片上传成功", filename: req.file.originalname, path: req.file.path }); } }); })
验证修复
重启服务器后,在 Postman 里重新发送请求:
- 确认请求方法是 POST,URL 正确
- 在
Body标签选择form-data,添加一个 key 为imageFile的项,类型选File,然后选一张格式符合要求的图片 - 确保 Headers 里只有认证头,没有手动设置的 Content-Type
- 发送请求,应该就能看到成功的响应,图片也会出现在
public/images文件夹里啦!
内容的提问来源于stack exchange,提问作者Asif Ahmed
相关产品推荐
相关产品推荐

