首页 > 解决方案 > 您如何在中间件中读取流并且仍然可以在下一个中间件中流式传输

问题描述

我正在使用代理中间件将多部分数据转发到不同的端点。我想使用以前的中间件从流中获取一些信息,并且仍然具有后面的代理中间件可读的流。是否有流模式允许我这样做?

function preMiddleware(req, res, next) {
  req.rawBody = '';

  req.on('data', function(chunk) {
    req.rawBody += chunk;
  });

  req.on('end', () => {
    next();
  })
}

function proxyMiddleware(req, res, next) {
  console.log(req.rawBody)
  console.log(req.readable) // false
}

app.use('/cfs', preMiddleware, proxyMiddleware)

我想在将流数据发送到外部端点之前访问 的name值。<input name="fee" type='file' />我认为我需要这样做,因为端点会解析fee为最终 url,并且我希望有一个句柄来进行一些后期处理。我愿意接受替代模式来解决这个问题。

标签: node.jsexpressstreammiddleware

解决方案


您需要能够向两个不同的方向发送单个流,如果您自己尝试,这并不容易 - 幸运的是,我在当天写了一个有用的模块rereadable-stream ,您可以使用它,我'将使用超燃冲压发动机来查找您感兴趣的数据。

我假设您的数据将是多部分边界:

const {StringStream} = require('scramjet');
const {ReReadable} = require("rereadable-stream");

// I will use a single middleware, since express does not allow to pass an altered request object to next()
app.use('/cfs', (req, res, next) => {
    const buffered = req.pipe(new ReReadable());        // rewind file to 
    let file = '';                                                  
    buffered.pipe(new StringStream)                     // pipe to a StringStream
        .lines('\n')                                    // split request by line
        .filter(x => x.startsWith('Content-Disposition: form-data;'))
                                                        // find form-data lines
        .parse(x => x.split(/;\s*/).reduce((a, y) => {  // split values
            const z = y.split(/:\s*/);                  // split value name from value
            a[z[0]] = JSON.parse(z[1]);                 // assign to accumulator (values are quoted)
            return a;
        }, {}))
        .until(x => x.name === 'fee' && (file = x.filename, 1))
                                                        // run the stream until filename is found
        .run()
        .then(() => uploadFileToProxy(file, buffered.rewind(), res, next))
                                                        // upload the file using your method

});

您可能需要稍微调整一下以使其在现实世界中工作。如果您遇到困难或上述答案中有什么需要解决的,请告诉我。


推荐阅读