NGINX 301 和 302 服务于小型 nginx 文档正文。有什么办法可以消除这种行为?

ano*_*one 6 nginx redirect 301-redirect

我们注意到,当使用 nginx 内部 301 和 302 处理时,nginx 将提供一个带有适当 Location: ... 标题的小文档正文。

类似于(在 html 中)的内容:301 重定向 - nginx。

根据上述行为,还发送内容类型 text/html 和内容长度标头。

我们做了很多 302 和一些 301 重定向,我们认为上述行为浪费了带宽。

有什么办法可以禁用这种行为?

我们想到的一个想法是将 error_page 301 302 设置为空文本文件。我们尚未对此进行测试,但我假设即使使用上述内容,也会发送 content-type 和 content-length (0) 标头。

那么,是否有一种干净的方法可以使用 nginx 发送“无主体”301/302 重定向?

Mic*_*ton 9

仔细考虑您的要求,并强烈考虑不要这样做

RFC 2616指定您要删除的实体主体应该存在。

10.3.2 301 永久移动

新的永久 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个简短的超文本注释,并带有指向新 URI 的超链接。

和...

10.3.3 302 发现

临时 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个简短的超文本注释,并带有指向新 URI 的超链接。

在这种情况下,应该在RFC 2119 中定义:

这个词,或形容词“推荐”,表示在特定情况下可能存在合理的理由忽略特定项目,但在选择不同的课程之前必须理解并仔细权衡全部含义。

现在您可以在不违反 RFC 的情况下执行此操作,但您应该了解全部含义:

  • 你做了很多工作,几乎没有任何好处。我能想到的禁用实体主体的唯一合乎逻辑的原因是节省带宽成本,这确实是您提到的原因,但差异非常小,您甚至不太可能在带宽图上看到差异。
  • 极少一部分 Web 客户端不会自动遵循 3xx 重定向。这个比例在编写 RFC 时要大得多,这就是为什么它首先存在的原因,但仍然有古老的怪物潜伏在黑暗的卧室和数据中心壁橱的阴影中,有时它们会出来玩。您最有可能看到的是curl,它仍然被普遍使用。

这个建议在RFC 7231 中有所放宽,它只是说(对于 301 和 302):

服务器的响应负载通常包含一个简短的超文本注释,其中包含指向新 URI 的超链接。

服务器的响应负载通常包含一个简短的超文本注释,其中包含指向不同 URI 的超链接。

  • 没有理由不这样做 https://serverfault.com/a/870911/110020。事实上,nginx 就是为了优化,所以,看起来 301/302 主体实际上从未包含任何链接,因为简单地携带这些链接来编写没人看过的文档是低效的。 (2认同)

cns*_*nst 8

是的,你绝对可以用 NGINX 做到这一点!

  • 只需安装一个异常处理程序,即error_page,即可对所需的响应进行后处理。确保以防止错误页面修改 HTTP 状态代码的方式设置它,例如,不要使用该=参数(或使用它来硬编码您想要的任何代码)。

  • 确保return响应带有返回状态代码,允许您有选择地设置[text],而不是URL.

  • 指定default_typeof "",这似乎删除了Content-Type标题

下面是完整的代码,也是我的GitHubStackOverflow.cnst.nginx.conf仓库:

# cat sf.421976.301-302-redirect-w-no-http-body-text.nginx.conf | sed 's#^#\t#g'
server {
    listen 1976;
    error_page 301 302 @30x; # keep original HTTP status code w/o `=`
    location @30x {
        default_type ""; # will remove Content-Type completely
        # `300` is a filler: client will get the original HTTP status code
        return 300;
    }
    return 301 http://example.su/test;
}
Run Code Online (Sandbox Code Playgroud)

这是它正常工作的确认:

% curl -i localhost:1976 | sed 's#^#\t#g'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.1
Date: Mon, 28 Aug 2017 22:02:41 GMT
Content-Length: 0
Connection: keep-alive
Location: http://example.su/test

%
Run Code Online (Sandbox Code Playgroud)

我已经在浏览器中尝试过它,它在那里也运行良好。

PS 另一种选择是修改源代码,并编辑ngx_http_error_301_pageet al 变量,但为什么要走硬路线?!^_^