使用 Multer 解析多部分 JSON

parse multipart JSON with Multer

我想使用通过 POST 从 IoT 摄像头发送的多部分 JSON 数据。 Express Body-parser 不支持多部分数据。

发送数据时可以附加或不附加图像。 Content-Disposition: form-data; name="event"; 是 JSON 数据,Content-Disposition: form-data; name="image"; 似乎是图像。图像的名称随每个事件而变化。

发送的数据如下:

POST { 
host: '192.168.1.1:3000',
  accept: '*/*',
  'content-length': '1178',
  'content-type': 'multipart/form-data; boundary=------------------------f519f81dc2e1d562'
}
--------------------------f519f81dc2e1d562
Content-Disposition: form-data; name="event"; filename="20200921204027_795989event_3913.json"
Content-Type: application/octet-stream

{"packetCounter":"3913",
"capture_timestamp":"1600677267347",
"frame_timestamp":"0",
"capture_ts":"1600677267347000000",
"plateUTF8":"RAR463",
"plateASCII":"RAR463",
 ......
"GEOtarget":"Camera",
"imagesURI":["/local/fflprapp/tools.cgi?action=getImage&name=14/20200921203427_524035lp_ABC123_3912.jpg","/local/fflprapp/tools.cgi?action=getImage&name=15/20200921203427_525568roi_ABC123_3912.jpg"],
"sensorProviderID":"testID"
}
-------------------------f519f81dc2e1d562--

我尝试使用 multer 使用 JSON 数据(我还不担心图像,在上面的请求中图像部分已关闭)是:

var express = require('express')
var multer = require('multer')
var upload = multer()
var app = express()

app.post('/', (req, res) => {
console.log('hello');
res.send(200);
});

app.listen(3000, () => { console.log('server running')});

请求进来时错误是:

dal@dal-ubuntu20lts-vm:~/test$ node index.js
server running
MulterError: Unexpected field
at wrappedFileFilter (/home/al/test/node_modules/multer/index.js:40:19)
at Busboy. (/home/al/test/node_modules/multer/lib/make-middleware.js:114:7)
at Busboy.emit (events.js:198:13)
at Busboy.emit (/home/al/test/node_modules/busboy/lib/main.js:38:33)
at PartStream. (/home/al/test/node_modules/busboy/lib/types/multipart.js:213:13)
at PartStream.emit (events.js:198:13)
at HeaderParser. (/home/al/test/node_modules/dicer/lib/Dicer.js:51:16)
at HeaderParser.emit (events.js:198:13)
at HeaderParser._finish (/home/al/test/node_modules/dicer/lib/HeaderParser.js:68:8)
at SBMH. (/home/al/test/node_modules/dicer/lib/HeaderParser.js:40:12)
MulterError: Unexpected field
at wrappedFileFilter (/home/al/test/node_modules/multer/index.js:40:19)
at Busboy. (/home/al/test/node_modules/multer/lib/make-middleware.js:114:7)
at Busboy.emit (events.js:198:13)
at Busboy.emit (/home/al/test/node_modules/busboy/lib/main.js:38:33)
at PartStream. (/home/al/test/node_modules/busboy/lib/types/multipart.js:213:13)
at PartStream.emit (events.js:198:13)
at HeaderParser. (/home/al/test/node_modules/dicer/lib/Dicer.js:51:16)
at HeaderParser.emit (events.js:198:13)
at HeaderParser._finish (/home/al/test/node_modules/dicer/lib/HeaderParser.js:68:8)
at SBMH. (/home/al/test/node_modules/dicer/lib/HeaderParser.js:40:12)

什么是意外字段以及如何解决此问题以便我可以访问 body.plateASCII 等数据

更新

即使只使用下面的代码,我也会得到输出:

[nodemon] starting 'node index.js'
server running
MulterError: Unexpected field

同样的错误 - 甚至没有得到控制台 Hello 语句。

如果我将其更改为接受任何文件:

app.post('/test', upload.any(), (req, res) => {
console.log('hello')
console.log('req.files: ', req.files)

我得到输出:

    hello
req.files:  [ { fieldname: 'event',
    originalname: '20200924191124_784695event_21006.json',
    encoding: '7bit',
    mimetype: 'application/octet-stream',
    buffer:
     <Buffer 7b 22 70 61 63 6b 65 74 43 6f 75 6e 74 65 72 22 3a 22 32 31 30 30 36 22 2c 0d 0a 22 63 61 70 74 75 72 65 5f 74 69 6d 65 73 74 61 6d 70 22 3a 22 31 36 ... >,
    size: 963 },
  { fieldname: 'image',
    originalname: '20200924185429_410383roi_ABC123_15179.jpg',
    encoding: '7bit',
    mimetype: 'image/jpeg',
    buffer:
     <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff db 00 43 00 06 04 05 06 05 04 06 06 05 06 07 07 06 08 0a 10 0a 0a 09 09 0a 14 0e 0f 0c ... >,
    size: 3182 } ]

您没有在您的示例中显示您实际使用 upload 变量的位置,但这是一个完整的示例:

var express = require('express')
var multer = require('multer')
var upload = multer({ storage: multer.memoryStorage() })  // 1
var app = express()

app.post('/', upload.single('event'), (req, res) => { // 2
  var data = JSON.parse(req.file.buffer.toString()) // 3

  console.log('hello')
  res.send(200)
})

app.listen(3000, () => {
  console.log('server running')
})
  1. 指定multer.memoryStorage()作为存储引擎使得上传文件的数据在内存中可用。

  2. upload.single('event') 添加了一个需要单个文件的中间件,字段名称 event 可以在发送到服务器的数据中看到。

  3. req.file.buffer.toString() 将数据的 Buffer 转换为字符串,假设它是 UTF-8(所有 JSON 都应该是)。 JSON.parse 然后将该字符串转换为 JavaScript 对象。

IoT 摄像头正在向响应发送 twp 部分。第一个是字段名 events,第二个是字段名 image.

app.post('/test', upload.any(), (req, res) => { // 1.accept any files
   console.log('POST recd')
   var data = JSON.parse(req.files[0].buffer.toString()) //2. decode the binary JSON
   ....

这将打印响应。