仅当在 Node.js 中发送响应没有错误时,如何设置缓存 headers
How to set cache headers only if there isn't an error in sending the response in Node.js
我基本上是这样做的:
app.get('/:id.:ext', (req, res) => {
const remote = bucket.file(`images/${req.params.id}.${req.params.ext}`)
// if (isProd)
// res.set('Cache-Control', 'public, max-age=604800')
remote.createReadStream({ validation: false })
.on('error', error => {
console.log(error)
res.send(`data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7`)
})
.pipe(res)
.on('end', () => {
res.set('Cache-Control', 'public, max-age=86400')
})
})
- 出现错误时,我只是return一个空图像。但是在这种情况下,我不想设置缓存headers,因为我不想缓存空白图像。
- 所以我尝试在响应发送后设置缓存 headers,但它们没有通过。
- 如果我在管道响应之前设置缓存 headers,我会缓存错误以防出错。
想知道如何解决这个问题。
你不能按照你想做的方式做你想做的事。 http 响应的顺序是发送 http headers,然后开始发送响应 body。因此,如果您要发送响应 body(就像您一样),您必须先发送 headers。您不能先发送响应 body,然后再改变主意 headers。他们已经被发送了。
并且,在 http 库已经开始发送响应 body 之后,您无法发送 headers。开始发送响应 body 写出与此响应一起使用的 http headers 当前存储的状态,然后开始写入响应。
据我所知,处理在发送 http 响应 body 过程中发生的错误的唯一方法是过早地关闭 http 连接。客户端将在没有看到 http 响应结束的情况下看到套接字关闭,并且将理解它得到了一个终止的、未完成的响应。此时您没有机会发送另一个回复。这种情况下的错误处理需要 client-side 才能决定要做什么。
另一种选择是在发送任何内容之前预取要发送给客户端的所有数据。这使您有最大的机会在开始发送 http 响应之前确定是否有任何内容会导致错误,然后您可以制作整个响应以匹配您的错误条件。如果你要这样做,你显然不能使用 .pipe(res)
之类的东西。相反,您必须将整个响应加载到内存中(或者至少是响应的一部分,如果您要分块发送)并且只有在成功 pre-flighted 并加载并准备好时开始发送回复了吗。
此外,另一种避免缓存错误图像的方法是对错误图像 URL 执行 301(临时重定向)而不是 return 将其作为对原始请求的响应。然后,当浏览器加载重定向 URL 并获取图像时,它不会将其缓存为原始 URL.
我基本上是这样做的:
app.get('/:id.:ext', (req, res) => {
const remote = bucket.file(`images/${req.params.id}.${req.params.ext}`)
// if (isProd)
// res.set('Cache-Control', 'public, max-age=604800')
remote.createReadStream({ validation: false })
.on('error', error => {
console.log(error)
res.send(`data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7`)
})
.pipe(res)
.on('end', () => {
res.set('Cache-Control', 'public, max-age=86400')
})
})
- 出现错误时,我只是return一个空图像。但是在这种情况下,我不想设置缓存headers,因为我不想缓存空白图像。
- 所以我尝试在响应发送后设置缓存 headers,但它们没有通过。
- 如果我在管道响应之前设置缓存 headers,我会缓存错误以防出错。
想知道如何解决这个问题。
你不能按照你想做的方式做你想做的事。 http 响应的顺序是发送 http headers,然后开始发送响应 body。因此,如果您要发送响应 body(就像您一样),您必须先发送 headers。您不能先发送响应 body,然后再改变主意 headers。他们已经被发送了。
并且,在 http 库已经开始发送响应 body 之后,您无法发送 headers。开始发送响应 body 写出与此响应一起使用的 http headers 当前存储的状态,然后开始写入响应。
据我所知,处理在发送 http 响应 body 过程中发生的错误的唯一方法是过早地关闭 http 连接。客户端将在没有看到 http 响应结束的情况下看到套接字关闭,并且将理解它得到了一个终止的、未完成的响应。此时您没有机会发送另一个回复。这种情况下的错误处理需要 client-side 才能决定要做什么。
另一种选择是在发送任何内容之前预取要发送给客户端的所有数据。这使您有最大的机会在开始发送 http 响应之前确定是否有任何内容会导致错误,然后您可以制作整个响应以匹配您的错误条件。如果你要这样做,你显然不能使用 .pipe(res)
之类的东西。相反,您必须将整个响应加载到内存中(或者至少是响应的一部分,如果您要分块发送)并且只有在成功 pre-flighted 并加载并准备好时开始发送回复了吗。
此外,另一种避免缓存错误图像的方法是对错误图像 URL 执行 301(临时重定向)而不是 return 将其作为对原始请求的响应。然后,当浏览器加载重定向 URL 并获取图像时,它不会将其缓存为原始 URL.