【问题标题】:Transform response of fastify-static served files转换 fastify-static 服务文件的响应
【发布时间】:2021-01-19 21:35:24
【问题描述】:

我正在使用 fastify 的 fastify-static 插件,并且需要转换它所服务的文件。例如,我想将“this-link”替换为“that-link”。我已经尝试过这里列出的各种 fastify.addHook() 事件,https://www.fastify.io/docs/latest/Hooks/,对我来说明智的是他们演示 [string].replace() 的“onSend”,但都失败了。对于 onSend 处理程序,有效负载不是可变字符串,而是看起来是 PassThrough 可读流。考虑到这一点,我尝试使用payload.on('data', (chunk) => {...}) 检查数据。那是有见地的。我可以看到文件文本,但我对流和 fastify 插件有点深入,不知道如何继续。

  1. 在使用 fastify-static 时,是否有一种简单的方法可以在响应发送之前对其进行转换? (为什么记录的 addHook() 失败了?)
  2. 假设我将有效负载正确解释为可读流,如何在 fastify-static 发送之前对其进行转换?

【问题讨论】:

    标签: node.js server fastify


    【解决方案1】:

    端点可以发送字符串、缓冲区或流。

    所以onSend 挂钩将接收其中一种数据类型。

    例如:

    const fastify = require('fastify')()
    const fs = require('fs')
    const path = require('path')
    
    fastify.addHook('onSend', async (request, reply, payload) => {
      console.log(`Payload is a ${payload}`);
      return typeof payload
    })
    
    fastify.get('/string', (req, reply) => { reply.send('a string') })
    fastify.get('/buffer', (req, reply) => { reply.send(Buffer.from('a buffer')) })
    fastify.get('/stream', (req, reply) => { reply.send(fs.createReadStream(__filename)) })
    
    
    fastify.inject('/string', (_, res) => console.log(res.payload))
    fastify.inject('/buffer', (_, res) => console.log(res.payload))
    fastify.inject('/stream', (_, res) => console.log(res.payload))
    

    fastify-static 将文件作为流发送,因此您需要实现一个转换流。 这是一个快速而肮脏的示例,假设存在一个带有内容的 static/hello 文件:

    你好%name

    const { Transform } = require('stream')
    const fastify = require('fastify')()
    const fs = require('fs')
    const path = require('path')
    
    const transformation = new Transform({
      writableObjectMode: false,
      transform(chunk, encoding, done) {
        const str = chunk.toString()
        this.push(str.replace('%name', 'foo bar'))
        done()
      }
    })
    
    fastify.addHook('onSend', async (request, reply, payload) => {
      if (typeof payload.pipe === 'function') {
        // check if it is a stream
        return payload.pipe(transformation)
      }
      return payload
    })
    
    fastify.register(require('fastify-static'), {
      root: path.join(__dirname, 'static'),
      prefix: '/static/',
    })
    
    fastify.inject('/static/hello', (_, res) => console.log(res.payload))
    

    作为建议,我会使用来自point-of-view 插件的模板系统,因为它支持这些开箱即用的功能。

    【讨论】:

    • 感谢您提供如此详尽的答案和模板系统提示!如果我不能以这种方式解决问题,我可能会切换到模板。我已经在静态预处理渲染上使用了把手。现在,出于开发和测试的原因,我正在尝试即时转换这些结果。您的代码使我朝着正确的方向前进,以更深入地了解流。不幸的是,我被困在两个问题上。第一个是错误“MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。”,这看起来很容易解决,但第二个是管道转换严重减慢了 fastify。
    猜你喜欢
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 2019-03-03
    • 2022-06-10
    • 2023-03-09
    相关资源
    最近更新 更多