在Express Node.js中禁用etag头

41
我们需要在Node.js Express应用程序中的所有HTTP响应中删除etag标头。我们在Express中编写了一个Web服务API,在向客户端发送ETags并且客户端发送if-none-match标头时,客户端看到意外结果。
我们尝试过app.disable('etag')res.removeHeader('etag'),但两者都不起作用。应用程序仍会发送标头。
是否有其他方法可以禁用所有响应中的此标头?
6个回答

67

app.disable('etag')现在应该可以正常工作了,已经合并了拉取请求来处理这个问题:

https://github.com/visionmedia/express/commit/610e172fcf9306bd5812bb2bae8904c23e0e8043

更新:正如Bigood在评论中指出的那样,现在处理这个问题的新方法如下:

app.set('etag', false); // turn off

变更发生于版本3.9.0:https://github.com/strongloop/express/releases/tag/3.9.0

有关设置ETag的更多选项,请参见此处的4.x文档:http://expressjs.com/4x/api.html#app.set


13
有没有一种方法可以仅针对特定端点禁用ETags?我不希望在我的API端点上使用ETags,但我希望在静态内容上使用ETags。 - Zambonilli
自3.9.0版本以来,这种方式不再起作用:https://github.com/strongloop/express/releases/tag/3.9.0 - Maen
@Zambonilli发布了如何在没有未记录的黑客攻击的情况下对每个端点进行微调的方法。https://dev59.com/1WUp5IYBdhLWcg3wj4Lu#51694492 - Lukas Liesis
Express使用ETag有什么作用?如果禁用了,会出现什么问题吗? - Time Killer

29
app.disable('etag')
这将禁用所有请求的etag头,但不包括静态内容。以下代码可针对静态内容实现此操作:
app.use(express.static(path.join(__dirname, 'public'), {
        etag: false
}));

2
这很重要,因为它很容易被忘记。 - crackmigg
2
这个没有文档说明,但是对于 res.sendFile('...', { etag: false }) 也是有效的。在我的情况下,app.disable('etag')app.set('etag', false) 都不起作用。 - youen

3

这个示例完美运行。

  1. No undocumented hacks
  2. Fine tuning for each endpoint
  3. Can add/remove any header :)

    var onHeaders = require('on-headers')
    
    function myRoute(req, res) {
      scrubETag(res)
      // do the rest
      res.send('something')
    }
    
    function scrubETag(res) {
      onHeaders(res, function () {
        this.removeHeader('ETag')
      })
    }
    

来源:https://github.com/expressjs/express/issues/2472

该问题的翻译内容不明确,请提供更具体的细节。

谢谢,这正是我在寻找的。 - funkizer
我刚刚在那个问题页面(#2472)上请求了一些确认,以查看是否仍然存在这个问题;因此,任何阅读此内容的人都可能希望监视该页面,以防有更新。 - Jason C

3

查看Express的response.js文件,只有在请求方法为GET时才会发送Etags标记。您可以在调用response.send()之前将请求方法设置为其他内容,以防止Express在响应中发送Etags标记。

例如:

app.get('/path/returnsJSON', function(req, res){
/* HACK to workaround the framework sending e-tags and "304 NOT MODIFIED" responses */
req.method="NONE"; // was "GET"
res.status(200).send({data:1}); 
});

对我来说,这个运作良好。


2

在我看来,解决您的问题的真正方法是找出为什么由于ETag而表现奇怪。

不过,回答您的问题,Express目前没有禁用ETag标头的支持。实际上,在此拉取请求中已经讨论并合并了它,但后来被撤销了。如果您确实需要此功能并且不想尝试修复根本问题,您可以应用该补丁,并从那里开始。


1
Y! Slow建议您移除ETags。 - chovy
我也看到了那个拉取请求,但是我希望有一个标准方法,而不是一种未来支持不好的修改。 - Raj
1
看起来他们最终把它拉了回来:https://github.com/visionmedia/express/pull/1694 - Nick Spacek

1

无法使用express

您只能将它们设置为false,但这仍会导致304重定向,因为您的ETag将与上次请求匹配(返回false

我使用了来自另一个npm包的此解决方案https://github.com/helmetjs/nocache/issues/9),该解决方案使用on-headers npm包在express添加ETag之后修改标题。

这可以添加到您调用res的任何位置,适用于特定路由或所有路由:

const onHeaders = require('on-headers');

onHeaders(res, function () {
    this.removeHeader('etag');
});

注意,您可能还需要更改缓存设置。但这会删除您的快速ETags :)


你确定吗?Matteo Collina提到在express中使用app.disable('etag')可以提升性能,详见这里 - Lonnie Best
从我所发现的来看,我确信这一点,但如果没有进一步研究,我无法对该讨论进行评论,因此那些偶然发现这篇文章的人需要自行进行研究。然而,我发现app.disable('etag')不起作用,所以不确定那个链接中的人是如何使其工作的 :/ - Kevin Danikowski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接