反向代理到静态网站不起作用
Reverse proxying to static website not working
我在 www.example.com 有一个 nginx 服务器 运行。
在其中,我设置了一个反向代理到我的托管在 Zeit now 的静态网站。
location /apps/app1/ {
proxy_pass https://app1.username.now.sh;
}
但是,当我访问 www.example.com/apps/app1 时,我得到了正确的浏览器选项卡名称('React App' 在我的例子中,因为我的静态网站是用 React 制作的,默认名称是 'React App' ).
在浏览器控制台中,我看到以下错误:
GET https://www.example.com/static/css/1.621e483e.chunk.css net::ERR_ABORTED 404 (Not Found)
GET https://www.example.com/manifest.json 404 (Not Found)
Manifest: Line: 1, column: 1, Unexpected token.
当我的静态网站托管在 Netlify. The Netlify customer service told me that they don't support reverse proxying, but that I could use their own redirects 时,我遇到了类似的问题。
为什么我无法在外部 URL 反向代理静态网站?有办法解决这个问题吗?
更新 1:
我目前正在尝试反向代理 bluprince13.com/apps/renting-vs-buying/ to renting-vs-buying.bluprince13.now.sh
可能您的路径与静态不匹配,因为当它加载时它在 /
上下文而不是 /apps/app1/
中寻找静态。因此,它不会匹配您的位置,也不会代理您的网站。
我建议您在代理和主机中使用相同的路径,否则您将需要重写 URL,但您将需要为您的应用程序服务的静态信息找到每个路径模式。
如果可能,请尝试在 /
上下文中使用 sub-domains 并放置相同的基本 headers 以帮助您的应用程序更好地解析。
server {
listen 80;
server_name app1.example.com;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://app1.username.now.sh/;
}
}
希望对您有所帮助。
请注意:我认为您应该避免使用反向代理。您确定没有其他更好的解决方案,例如设置 CNAME 记录 DNS 吗?
你应该这样做吗?
我不建议这样做,原因很简单:因为你无法控制上游,而且他们明确告诉你他们不支持你的方案,他们可以随时决定阻止你的代理服务器时间,然后由于不受支持的设置,您的整个网站将关闭。这就是许多人在过去尝试使用 Cloudflare 修复损坏的 Tumblr 时发生的情况(过去,从 Tumblr 获取空白页面非常普遍,因此,将 Cloudflare 放在它前面,实际上确实提高了速度它,并修复了空白页问题。
怎么做。
不过,如果你还想用nginx来做,那真的很简单,而且这是一个围绕nginx很受欢迎的问题:
你基本上只需要将 front-end 上的 /apps/app1/
映射到后端的 /
,它可以像这样完成 - 注意尾部斜杠非常重要此处 — 根据 http://nginx.org/r/proxy_pass(将其称为 "URI" 的存在):
location /apps/app1/ {
proxy_pass https://app1.username.now.sh/; # DO NOT REMOVE trailing slash!
}
这是可能的,但有其技术缺点(除了明显考虑到您可能违反了上游的服务条款)。
我的整个配置如下所示:
server {
server_name localhost;
listen *:8000;
location /apps/ {
sub_filter 'href="/c' 'href="/apps/c';
sub_filter 'href="/f' 'href="/apps/f';
sub_filter 'href="/m' 'href="/apps/m';
sub_filter 'href="/s' 'href="/apps/s';
sub_filter 'src="/s' 'src="/apps/s';
sub_filter_once off;
proxy_set_header Accept-Encoding "";
proxy_pass https://renting-vs-buying.bluprince13.now.sh/;
}
}
此处 Nginx 配置为使用其 sub_filter
模块替换响应的某些部分。我们指定要查找和替换的字符串。由于您的 HTML 可能是由 Webpack 之类的东西生成的并且没有换行符,我们需要在每一行中重复替换,这就是为什么 sub_filter_once off
.
关于 Accept-Encoding
。 Nginx 能够在 text/html
响应中执行替换。仅有的。这意味着没有压缩。由于后端喜欢以压缩内容响应,我们要求它不要这样做。
几点注意事项:
- 过滤器的静态列表很脆弱:当在后端添加一些新前缀时,您的应用程序可能会崩溃;
- 您正在浪费代理和后端之间的带宽,因为无法使用压缩。
我建议最好的选择是更改您的应用程序,使其在 /apps
前缀下响应。你会立即避免所有头痛。
以下是对我有用的方法,但我只是在下面回答的其他人的帮助下才弄明白的。事后看来,这似乎很简单,我自己都没有想出来,我觉得很傻!
响应的 HTML 包含 CSS 和 JS 文件的绝对 URL。浏览器最初从 /apps/app1 前缀加载 HTML 页面,但随后它尝试从 /static、/favicon、/css 等加载资源。但是,那里什么也没有!
问题是应用程序使用了绝对引用。我所需要做的就是更改我的应用程序以改为使用相对引用。使用 React,您可以通过将其放入 package.json 中轻松地做到这一点(请参阅文档 here):
"homepage": ".",
现在,浏览器将从 /apps/app1/static、/apps/app1/favicon、/apps/app1/css 等正确加载资源
我在 www.example.com 有一个 nginx 服务器 运行。
在其中,我设置了一个反向代理到我的托管在 Zeit now 的静态网站。
location /apps/app1/ {
proxy_pass https://app1.username.now.sh;
}
但是,当我访问 www.example.com/apps/app1 时,我得到了正确的浏览器选项卡名称('React App' 在我的例子中,因为我的静态网站是用 React 制作的,默认名称是 'React App' ).
在浏览器控制台中,我看到以下错误:
GET https://www.example.com/static/css/1.621e483e.chunk.css net::ERR_ABORTED 404 (Not Found)
GET https://www.example.com/manifest.json 404 (Not Found)
Manifest: Line: 1, column: 1, Unexpected token.
当我的静态网站托管在 Netlify. The Netlify customer service told me that they don't support reverse proxying, but that I could use their own redirects 时,我遇到了类似的问题。
为什么我无法在外部 URL 反向代理静态网站?有办法解决这个问题吗?
更新 1: 我目前正在尝试反向代理 bluprince13.com/apps/renting-vs-buying/ to renting-vs-buying.bluprince13.now.sh
可能您的路径与静态不匹配,因为当它加载时它在 /
上下文而不是 /apps/app1/
中寻找静态。因此,它不会匹配您的位置,也不会代理您的网站。
我建议您在代理和主机中使用相同的路径,否则您将需要重写 URL,但您将需要为您的应用程序服务的静态信息找到每个路径模式。
如果可能,请尝试在 /
上下文中使用 sub-domains 并放置相同的基本 headers 以帮助您的应用程序更好地解析。
server {
listen 80;
server_name app1.example.com;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://app1.username.now.sh/;
}
}
希望对您有所帮助。
请注意:我认为您应该避免使用反向代理。您确定没有其他更好的解决方案,例如设置 CNAME 记录 DNS 吗?
你应该这样做吗?
我不建议这样做,原因很简单:因为你无法控制上游,而且他们明确告诉你他们不支持你的方案,他们可以随时决定阻止你的代理服务器时间,然后由于不受支持的设置,您的整个网站将关闭。这就是许多人在过去尝试使用 Cloudflare 修复损坏的 Tumblr 时发生的情况(过去,从 Tumblr 获取空白页面非常普遍,因此,将 Cloudflare 放在它前面,实际上确实提高了速度它,并修复了空白页问题。
怎么做。
不过,如果你还想用nginx来做,那真的很简单,而且这是一个围绕nginx很受欢迎的问题:
你基本上只需要将 front-end 上的 /apps/app1/
映射到后端的 /
,它可以像这样完成 - 注意尾部斜杠非常重要此处 — 根据 http://nginx.org/r/proxy_pass(将其称为 "URI" 的存在):
location /apps/app1/ {
proxy_pass https://app1.username.now.sh/; # DO NOT REMOVE trailing slash!
}
这是可能的,但有其技术缺点(除了明显考虑到您可能违反了上游的服务条款)。
我的整个配置如下所示:
server {
server_name localhost;
listen *:8000;
location /apps/ {
sub_filter 'href="/c' 'href="/apps/c';
sub_filter 'href="/f' 'href="/apps/f';
sub_filter 'href="/m' 'href="/apps/m';
sub_filter 'href="/s' 'href="/apps/s';
sub_filter 'src="/s' 'src="/apps/s';
sub_filter_once off;
proxy_set_header Accept-Encoding "";
proxy_pass https://renting-vs-buying.bluprince13.now.sh/;
}
}
此处 Nginx 配置为使用其 sub_filter
模块替换响应的某些部分。我们指定要查找和替换的字符串。由于您的 HTML 可能是由 Webpack 之类的东西生成的并且没有换行符,我们需要在每一行中重复替换,这就是为什么 sub_filter_once off
.
关于 Accept-Encoding
。 Nginx 能够在 text/html
响应中执行替换。仅有的。这意味着没有压缩。由于后端喜欢以压缩内容响应,我们要求它不要这样做。
几点注意事项:
- 过滤器的静态列表很脆弱:当在后端添加一些新前缀时,您的应用程序可能会崩溃;
- 您正在浪费代理和后端之间的带宽,因为无法使用压缩。
我建议最好的选择是更改您的应用程序,使其在 /apps
前缀下响应。你会立即避免所有头痛。
以下是对我有用的方法,但我只是在下面回答的其他人的帮助下才弄明白的。事后看来,这似乎很简单,我自己都没有想出来,我觉得很傻!
响应的 HTML 包含 CSS 和 JS 文件的绝对 URL。浏览器最初从 /apps/app1 前缀加载 HTML 页面,但随后它尝试从 /static、/favicon、/css 等加载资源。但是,那里什么也没有!
问题是应用程序使用了绝对引用。我所需要做的就是更改我的应用程序以改为使用相对引用。使用 React,您可以通过将其放入 package.json 中轻松地做到这一点(请参阅文档 here):
"homepage": ".",
现在,浏览器将从 /apps/app1/static、/apps/app1/favicon、/apps/app1/css 等正确加载资源