如何将可读流添加到数据并发布

时间:2018-08-21 07:39:45

标签: node.js stream

我是一个新的nodejs流。我想在服务器A中创建一个流,该流可以在解析multipart / form-data请求之后存储文件,然后将该流附加到另一个表单以发布到服务器B。

但是,当我在服务器B中收到请求时,请求标头的内容长度比文件大小小得多,并引发错误“解析错误,堆栈:错误:解析错误”。

有人可以告诉我怎么了吗?非常感谢你!

这是我的代码, body-parse.js ----一种用于解析req并创建流以存储缓冲区的中间件

async function formHandler2(req, res, next) {
    const contentType = req.headers['content-type'] || ''
    if (contentType.indexOf('multipart') === 0) {
        try {
            let form = new formidable.IncomingForm({ multiples: true })
            req.body = req.body || {}
            form.onPart = function(part) {
                let isField = false,
                    buffers = []
                if (!part.filename) {
                    console.log(` ****** formidable field ***** ${part.name}`)
                    isField = true
                } else {
                    console.log(` ****** formidable files ***** ${part.name} ${part.filename}`)
                }

                this._flushing++
                const readableStream = new stream.Readable({
                    highWaterMark: 64 * 1024, // 64KB
                })

                // this.emit('fileBegin', part.name, file)
                part.on('data', (buffer) => {
                    if (buffer.length == 0) {
                        return ''
                    }
                    if (isField) {
                        buffers.push(buffer)
                    } else {
                        readableStream.push(buffer)
                    }

                    //this.pause()
                    //this.resume()
                })
                part.once('end', () => {
                    if (isField) {
                        req.body[part.name] = Buffer.concat(buffers).toString()
                        console.log(
                            ` ****** formidable field ***** ${part.name} ${req.body[part.name]}`
                        )
                    } else {
                        if (!req.body[part.name]) {
                            req.body[part.name] = []
                        }
                        console.log('----------- readableStream end')
                        readableStream.push(null)
                        readableStream._readableState.sync = false
                        console.log(readableStream._readableState.buffer)
                        req.body[part.name].push(readableStream)
                    }

                    this._flushing--
                    // this.emit('file', part.name, file)
                    this._maybeEnd()

                    // req.body[part.name].push(stream)
                    //part.resume()
                })

                part.on('error', (err) => {
                    console.log('part parse error', err)
                })
            }

            form.on('end', function() {
                console.log('Upload completed!')
                next()
            })

            form.parse(req)
        } catch (err) {
            console.log('formHandler', err)
            res.send({
                success: false,
                message: err.message ? err.message : err,
            })
        }
    } else {
        if (is.empty(req.body)) {
            req.body = is.empty(req.query) ? null : req.query
        }
        next()
    }
}

addPersonnel.js ----将表单发布到服务器B

          const RP = require('request-promise')

    async function add(req, res) {
        try {
            const username = req.session.username
            const { UID, SID, name, description, personType, avatars } = req.body
            const newPersonnel = await RP({
                url: URL.personnel.add,
                method: 'POST',
                formData: {
                    UID,
                    SID,
                    name,
                    description,
                    personType,
                    avatars
                }
            })
            res.send({ success: true, newPersonnel })
        } catch (err) {
            res.goError({ error: err })
        }
    }

这是在服务器A中登录的请求信息,

{ method: 'POST',
  url: 'http://localhost:3500/v1/personnel/new',
  formData: 
  { UID: '5aeac7413872ec3ae93f1d71',
    SID: '5aeac7643872ec3ae93f1d73',
    name: 'a',
    personType: 'staff',
    description: '',
    avatar: 
      [ Readable {
          _readableState: 
          ReadableState {
            objectMode: false,
            highWaterMark: 65536,
            buffer: 
              BufferList {
                head: 
                { data: <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 08 06 06 07 06 05 08 07 07 07 09 09 08 0a 0c 14 0d 0c 0b 0b 0c 19 12 13 0f ... >,
                  next: 
                    { data: <Buffer 0d>,
                      next: 
                      { data: <Buffer 20 ef fd 69 17 4f c5 ac 69 fa d4 25 ed 65 ff 00 0f 9b e4 b9 5c 65 19 08 e7 35 7f 4f 75 b5 8d d5 b4 76 5a c8 9a 29 23 e0 4f 1a ee 0c 3e a3 b8 ad 2b f5 ... >,
                        next: null } } },
                tail: 
                { data: <Buffer 20 ef fd 69 17 4f c5 ac 69 fa d4 25 ed 65 ff 00 0f 9b e4 b9 5c 65 19 08 e7 35 7f 4f 75 b5 8d d5 b4 76 5a c8 9a 29 23 e0 4f 1a ee 0c 3e a3 b8 ad 2b f5 ... >,
                  next: null },
                length: 3 },
            length: 14047,
            pipes: null,
            pipesCount: 0,
            flowing: null,
            ended: true,
            endEmitted: false,
            reading: false,
            sync: false,
            needReadable: false,
            emittedReadable: true,
            readableListening: false,
            resumeScheduled: false,
            destroyed: false,
            defaultEncoding: 'utf8',
            awaitDrain: 0,
            readingMore: false,
            decoder: null,
            encoding: null },
          readable: true,
          domain: null,
          _events: {},
          _eventsCount: 0,
          _maxListeners: undefined } ] }
}

如您所见,缓冲区长度:14047。但是,在服务器B上,内容长度:“ 789”,该长度比文件小得多。另外,还会引发错误:消息:解析错误,堆栈:错误:解析错误。

{ token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiI2NW51Zjk4Z2ZvOGN1djhsaHQ4NDFuZDRvYmhqbzM4OWIzOG1rOGphIiwic2FsdCI6ImQwMTd1aHA0ZXZsZzBxcW03bzNoc3JlbTRqaTJwMjdpIiwiYWNjb3VudCI6Im1lbmdxaWhlQHR1cHV0ZWNoLmNvbSIsIlVJRCI6IiIsImlhdCI6MTUzNDc3MjM0OCwiZXhwIjoxNTM0Nzc5NTQ4fQ.y8Izt85VnL9eMEn4O34CfddZJcGMqhCwUMKocKZQiiY',
  'ref-user': 'mengqihe@tuputech.com',
  host: 'localhost:3500',
  'content-type': 'multipart/form-data; boundary=--------------------------650686709075962079495394',
  'content-length': '789',
  connection: 'close' }

我已经在这里停留了几天...我的代码有什么问题?

0 个答案:

没有答案