nginx接收到post请求.请求报文里是一个json字符串,字符串里有个字段id。
根据id不同,转发到不同地址。
如果id=aaa,转发到www.aaa.com.test
如果id=bbb,转发到www.bbb.com.test
如何配置,请提供一个nginx.conf
要在 Nginx 中根据 POST 请求的 JSON 负载中的 id
字段的值进行转发,你可以使用 Nginx 的 ngx_http_lua_module
模块,这个模块允许你在 Nginx 配置中使用 Lua 脚本。下面是一个示例配置,它展示了如何根据 POST 请求的 JSON 负载中的 id
字段的值来转发请求。
首先,确保你的 Nginx 已经安装了 lua-nginx-module
和 lua-resty-http
库。这些可以通过 OpenResty 来安装,OpenResty 是一个集成了常用模块的 Nginx 发行版。
安装 OpenResty
你可以通过以下命令安装 OpenResty(假设你使用的是基于 Debian 的系统,如 Ubuntu):
bash
sudo apt-get update
sudo apt-get install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl -O https://openresty.org/package/pubkey.gpg
sudo apt-key add pubkey.gpg
sudo apt-get install -y apt-transport-https
echo "deb https://openresty.org/package/debian $(lsb_release -sc) openresty" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt-get update
sudo apt-get install -y openresty
Nginx 配置 (nginx.conf
)
下面是一个示例的 nginx.conf
配置,它使用 Lua 脚本来解析 POST 请求的 JSON 负载,并根据 id
字段的值转发请求。
nginx
http {
lua_package_path "/usr/local/openresty/luajit/share/lua/5.1/?.lua;;";
lua_shared_dict my_cache 10m;
server {
listen 80;
location / {
content_by_lua_block {
-- 读取 POST 请求体
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then
ngx.status = ngx.HTTP_BAD_REQUEST
ngx.say("No request body found")
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
-- 解析 JSON
local cjson = require "cjson.safe"
local json_data = cjson.decode(data)
if not json_data or not json_data.id then
ngx.status = ngx.HTTP_BAD_REQUEST
ngx.say("Invalid JSON or missing 'id' field")
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
local id = json_data.id
local target_url
if id == "aaa" then
target_url = "http://www.aaa.com.test"
elseif id == "bbb" then
target_url = "http://www.bbb.com.test"
else
ngx.status = ngx.HTTP_NOT_FOUND
ngx.say("Unknown 'id' value")
return ngx.exit(ngx.HTTP_NOT_FOUND)
end
-- 创建 HTTP 客户端并转发请求
local http = require "resty.http"
local httpc = http.new()
local res, err = httpc:request_uri(target_url, {
method = ngx.var.request_method,
body = data,
headers = ngx.req.get_headers(),
keepalive = false,
})
if not res then
ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
ngx.say("Failed to forward request: ", err)
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
-- 设置响应头
for k, v in pairs(res.headers) do
ngx.header[k] = v
end
-- 发送响应体
ngx.status = res.status
ngx.print(res.body)
-- 关闭 HTTP 客户端
httpc:close()
}
}
}
}
解释
- lua_package_path 和 lua_shared_dict:设置 Lua 模块的搜索路径和共享字典。
- server 和 location:定义一个服务器块和一个位置块来处理进入的请求。
- content_by_lua_block:使用 Lua 脚本处理请求。
- ngx.req.read_body():读取 POST 请求体。
- cjson.decode(data):解析 JSON 数据。
- 条件判断 :根据
id
字段的值决定目标 URL。 - resty.http :使用
resty.http
模块创建 HTTP 客户端并转发请求。 - 设置响应头和状态:将目标服务器的响应头和状态码传递给客户端。
- 发送响应体:将目标服务器的响应体发送给客户端。
确保你安装了 lua-cjson
和 lua-resty-http
库,这通常在使用 OpenResty 时已经包含在内。如果你手动安装 Nginx 和 Lua 模块,则需要确保这些库可用。
重启 Nginx
在修改完 nginx.conf
后,不要忘记重启 Nginx 以应用新的配置:
bash
sudo systemctl restart nginx
这样,Nginx 将能够根据 POST 请求的 JSON 负载中的 id
字段的值来转发请求。