首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在中间件中读取流,并且在下一个中间件中仍然可以流传输?

如何在中间件中读取流,并且在下一个中间件中仍然可以流传输?
EN

Stack Overflow用户
提问于 2018-05-08 22:24:42
回答 2查看 752关注 0票数 0

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

代码语言:javascript
运行
复制
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)

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

EN

回答 2

Stack Overflow用户

发布于 2018-05-09 01:43:44

我不认为有任何机制可以在不从流中永久移除数据的情况下窥视流,也不存在从流中“取消读取”数据以将其放回流中的任何机制。

因此,我可以想到一些可能的想法:

  1. 从流中读取所需的数据,然后手动将数据发送到最终终结点(不使用需要可读流的代理代码)。
  2. 读取流,获取所需的数据(如果需要),然后创建一个新的可读流,将读取的数据放入该可读流中,并将该可读流传递到代理上。确切地说,如何传递它,只是代理需要检查一下代理代码。您可能需要创建一个新的req对象,即新的流。
  3. 创建一个流转换,允许您在创建可以提供给您自己的data事件处理程序的新流的同时读取流(甚至可能修改它),然后暂停流(注册数据甚至会自动触发流流动,而您不希望它流动),然后立即调用next()。我认为这将允许您在代理中间件读取流时“看到”所有经过的数据的副本,因为将有多个data事件处理程序,一个用于您的中间件,另一个用于代理中间件。这只是一个理论上的想法--我还没有尝试过。
票数 1
EN

Stack Overflow用户

发布于 2018-05-10 04:11:04

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

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

代码语言:javascript
运行
复制
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

});

您可能需要对此稍作调整,才能使其在真实场景中工作。如果你在上面的回答中遇到问题或者有什么需要解决的,请告诉我。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50235984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档