1

我正在尝试让 nginx 在同一域的子路径上代理各种应用程序。

我的问题是应用程序生成的链接/用作它们的根而不是它们的子目录。

我的配置是:

location /wiki/ {
    proxy_pass http://localhost:4567/;
    proxy_set_header SCRIPT_NAME /wiki;
}

我认为proxy_set_header SCRIPT_NAME /wiki;应该设置 header SCRIPT_NAME,应用程序使用它来生成链接,而是HTTP_SCRIPT_NAME设置,应用程序忽略它。

如何设置SCRIPT_NAME以便正确生成我的链接?

4

1 回答 1

2

根据CGI 规范,http 标头带有HTTP_前缀:

Meta-variables with names beginning with "HTTP_" contain values read
from the client request header fields, if the protocol used is HTTP.
The HTTP header field name is converted to upper case, has all
occurrences of "-" replaced with "_" and has "HTTP_" prepended to
give the meta-variable name.

也就是说,标题Some-Header将被视为HTTP_SOME_HEADER在您的应用程序中。也就是说,一切正常 - 您添加了 http 标头,并使用HTTP_前缀使其可用。

SCRIPT_NAME变量是特殊的,不是由任何标头设置的,而是由运行应用程序的代码从 URI 构造的。要更改它,您必须实际更改后端看到的 URI,即您需要

proxy_pass http://localhost:4567/wiki/;

或者只是/wiki/在proxy_pass中没有,只要它在location /wiki/,即

location /wiki/ {
    proxy http://localhost:4567;
}

这里的坏事是您可能出于某种原因将 URI 从 更改/wiki//,即您的后端应用程序期望/. 这个问题有几种可能的解决方案:

  1. 实际上将应用程序移动到/wiki/. 通常这很容易做到。
  2. 更改您的应用程序以通过一些带外方法接受其用于生成链接等的基本 url。许多应用程序已经通过一些配置选项支持这一点。
  3. 尝试用 nginx 本身替换您的应用程序返回的内容。有几个 nginx 指令可以做到这一点,特别是proxy_redirectproxy_cookie_pathsub filter。这是最脆弱的方法,除非您知道您的应用程序返回什么以及必须替换什么,否则不推荐使用它。
于 2012-11-11T13:33:58.137 回答