转换 fastify-static 服务文件的响应
Transform response of fastify-static served files
我正在使用 fastify 的 fastify-static 插件,需要转换它提供的文件。例如,我想用“that-link”替换“this-link”。我已经尝试了此处列出的各种 fastify.addHook() 事件,https://www.fastify.io/docs/latest/Hooks/,对我来说明智的是“onSend”,它们在其中演示了 [string].replace(),但都失败了。对于 onSend 处理程序,有效负载不是可变字符串,而是看起来是 PassThrough 可读流。考虑到这一点,我尝试使用 payload.on('data', (chunk) => {...})
检查数据。那是有见地的。我可以看到文件文本,但我正在深入研究流和 fastify 插件,但不确定如何继续。
- 在使用 fastify-static 时,是否有一种简单的方法可以在发送响应之前对其进行转换? (为什么记录的 addHook() 失败了?)
- 假设我正确地将负载解释为可读流,我如何在 fastify-static 发送它之前转换它?
端点可以发送字符串、缓冲区或流。
因此 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
文件存在,内容为:
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 插件的模板系统,因为它支持开箱即用的这些类型的功能。
我正在使用 fastify 的 fastify-static 插件,需要转换它提供的文件。例如,我想用“that-link”替换“this-link”。我已经尝试了此处列出的各种 fastify.addHook() 事件,https://www.fastify.io/docs/latest/Hooks/,对我来说明智的是“onSend”,它们在其中演示了 [string].replace(),但都失败了。对于 onSend 处理程序,有效负载不是可变字符串,而是看起来是 PassThrough 可读流。考虑到这一点,我尝试使用 payload.on('data', (chunk) => {...})
检查数据。那是有见地的。我可以看到文件文本,但我正在深入研究流和 fastify 插件,但不确定如何继续。
- 在使用 fastify-static 时,是否有一种简单的方法可以在发送响应之前对其进行转换? (为什么记录的 addHook() 失败了?)
- 假设我正确地将负载解释为可读流,我如何在 fastify-static 发送它之前转换它?
端点可以发送字符串、缓冲区或流。
因此 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
文件存在,内容为:
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 插件的模板系统,因为它支持开箱即用的这些类型的功能。