我有一个 Web 应用程序想要在未启用 CORS 的情况下从第三方站点访问文件。请求可以是具有任意参数的任意域。我正在向我的域发送一个请求,其中包含编码为 GET 参数的目标,即
GET https://www.example.com/proxy/?url=http%3A%2F%2Fnginx.org%2Fen%2Fdocs%2Fhttp%2Fngx_http_proxy_module.html
然后在 Nginx 中我做
location /proxy/ {
resolver 8.8.8.8;
set_unescape_uri $dst $arg_url;
proxy_pass $dst;
}
这适用于单个文件,但目标服务器有时会返回一个 Location 标头,我想拦截并修改该标头以便客户端重试。
基本上我想转义 $sent_http_location,将其附加到https://www.example.com/proxy/?url=并将其传回浏览器以重试。
我试过做
set_escape_uri $tmp $sent_http_location;
proxy_redirect $sent_http_header /pass/?v=$tmp;
但这行不通。我还尝试保存 Location 标头,然后忽略传入的标头
proxy_hide_header
并用我自己的替换它
proxy_set_header
但忽略会导致我丢失保存它的变量。
如何配置 Nginx 来完成重定向处理,以便在代理站点重定向时将编码的 URL 返回给用户?
您的不成功方法存在几个问题:
proxy_set_header
设置发送到上游服务器而不是客户端的标头。所以即使$sent_http_location
不为空,您的配置不可能按您希望的方式工作。
$sent_http_<header>
变量指向与将发送到客户端的响应标头完全相同的内存区域。所以当proxy_hide_header
生效后,指定的标头以及相应的值将从内存中删除$sent_http_<header>
.
set_escape_uri
在请求处理的早期阶段工作,早于proxy_pass
被称为并且Location
header是从上游服务器返回的。所以它总是会处理当时的空变量$sent_http_location
并且结果也将始终是空变量。
最后一个问题是最严重的。唯一的办法就是制作set_escape_uri
之后工作proxy_pass
是强制Nginx离开当前位置并重新开始处理。这可以通过error_page
trick:
location /proxy/ {
resolver 8.8.8.8;
set_unescape_uri $dst $arg_url;
proxy_pass $dst;
proxy_intercept_errors on;
error_page 301 = @rewrite_301;
}
location @rewrite_301 {
set_escape_uri $location $upstream_http_location;
return 301 /pass/?v=$location;
}
注意使用$upstream_http_location
代替$sent_http_location
。当 Nginx 离开该位置的上下文时,它假设请求将被代理到另一个上游,或者以其他方式处理,因此它会清除从最后收到的标头proxy_pass
,为新的响应标头腾出空间。
Unlike $sent_http_<header>
变量,表示将发送到客户端的响应标头,$upstream_http_<header>
变量表示从上游收到的响应标头。因此,只有当请求代理到另一个上游服务器时,它们才会被新值替换。因此,一旦设置,这些变量就可以随时使用,并且不会被清除。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)