乐闻世界logo
搜索文章和话题

如何使用nginx通过代理传递查询字符串参数

6 个月前提问
3 个月前修改
浏览次数134

6个答案

1
2
3
4
5
6

当您使用 Nginx 作为代理服务器时,将查询字符串参数从客户端传递到上游服务器(例如应用服务器)是一个很常见的需求。Nginx 默认情况下就会将请求中的查询字符串参数传递到上游服务器。这是因为当请求被代理时,整个请求行(包括 URI 和查询字符串)都会被转发。

以下是一个基本的 Nginx 配置示例,展示了如何为一个应用服务器配置代理,并自动包含查询字符串:

nginx
server { listen 80; server_name example.com; location / { # 代理设置,将请求传递到后端应用服务器 proxy_pass http://backend_server; # 下面这些是一些通用的代理设置,以确保请求和响应头被合适地处理 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

在这个配置中,proxy_pass 指令用来定义上游服务器的地址。当客户端发送请求到 Nginx 时,如果请求包含查询字符串,Nginx 将自动将整个请求 URI(包括查询字符串)转发到 http://backend_server

例如,如果客户端请求 http://example.com/search?q=openai&lang=en,Nginx 会将这个请求代理到 http://backend_server/search?q=openai&lang=en,包括查询字符串 ?q=openai&lang=en

如果您需要修改查询字符串或者根据查询字符串做一些特殊处理,可以使用 rewrite 指令或者 $args 变量来实现。这里是一个使用 rewrite 指令修改查询字符串的示例:

nginx
server { listen 80; server_name example.com; location / { # 检查请求的查询字符串,如果没有 lang 参数则添加 lang=en if ($args !~ "lang=") { set $args "${args}&lang=en"; } # 将修改后的请求传递到后端服务器 proxy_pass http://backend_server; # 其余代理设置... } }

在这个例子中,如果原始请求缺少 lang 参数,Nginx 将会添加 lang=en 到查询字符串,并将修改后的请求传递到上游服务器。

2024年6月29日 12:07 回复

来自proxy_pass文档:

一种特殊情况是在 proxy_pass 语句中使用变量:不使用请求的 URL,您完全负责自己构建目标 URL。

由于您在目标中使用 $1,因此 nginx 依赖于您准确地告诉它要传递的内容。您可以通过两种方式解决此问题。首先,使用 proxy_pass 剥离 uri 的开头很简单:

shell
location /service/ { # Note the trailing slash on the proxy_pass. # It tells nginx to replace /service/ with / when passing the request. proxy_pass http://apache/; }

或者,如果您想使用正则表达式位置,只需包含参数:

shell
location ~* ^/service/(.*) { proxy_pass http://apache/$1$is_args$args; }
2024年6月29日 12:07 回复

我使用 kolbyjack 的第二种方法的稍微修改版本,而~不是~*.

shell
location ~ ^/service/ { proxy_pass http://apache/$uri$is_args$args; }
2024年6月29日 12:07 回复

你必须使用 rewrite 来使用 proxy_pass 传递参数,这是我为 angularjs 应用程序部署到 s3 所做的示例

S3 静态网站托管将所有路径路由到 Index.html

适应你的需求会是这样的

shell
location /service/ { rewrite ^\/service\/(.*) /$1 break; proxy_pass http://apache; }

如果你想结束在http://127.0.0.1:8080/query/params/

如果你想最终进入http://127.0.0.1:8080/service/query/params/ 你需要类似的东西

shell
location /service/ { rewrite ^\/(.*) /$1 break; proxy_pass http://apache; }
2024年6月29日 12:07 回复

我修改了 @kolbyjack 代码以使其适用

shell
http://website1/service http://website1/service/

带参数

shell
location ~ ^/service/?(.*) { return 301 http://service_url/$1$is_args$args; }
2024年6月29日 12:07 回复

你的答案