说明
使用lua统一转发请求的方案,也可以使用nginx的配置项proxy_pass
来解决,
但是引入lua,可以让处理方式更灵活。
# 将8081端口的“.json”请求,转发到8001端口
# 自动携带原请求的查询参数,get和post请求都可以转发,
# 转发后的请求类型和原请求一致
location ~* /.*\.json$ {
# 将原始请求路径放到“x-original-uri”请求头中
proxy_set_header x-original-uri $uri;
proxy_pass http://127.0.0.1:8001/mock/ajax?$args;
}
1. OpenResty
1.1 安装OpenResty
$ brew install homebrew/nginx/openresty
1.2 安装http模块和json模块
$ git clone https://github.com/pintsized/lua-resty-http.git
$ cp lua-resty-http/lib/resty/* /usr/local/Cellar/openresty/1.11.2.5/lualib/resty/
$ git clone https://github.com/rxi/json.lua.git
$ cp json.lua/json.lua /usr/local/Cellar/openresty/1.11.2.5/lualib/resty/
1.3 修改环境变量
打开~/.zshrc
,在文件末尾加上,
export PATH=/usr/local/Cellar/openresty/1.11.2.5/nginx/sbin:$PATH
然后执行source
命令,
$ source ~/.zshrc
2. Nginx配置
2.1 站点文件结构
$ mkdir test-openresty
新建conf/nginx.conf
文件,conf/ajax.lua
文件和logs
文件夹,
目录结构如下,
test-openresty
├── conf
│ ├── ajax.lua
│ └── nginx.conf
└── logs
2.2 conf/nginx.conf
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
server {
listen 8081;
# 将8081端口的“.json”请求,交给lua处理
location ~* /.*\.json$ {
# 设置字符集
charset UTF-8;
# 设置ngx.var.redirect_url变量
set $redirect_url http://127.0.0.1:8001/mock/ajax/;
# 使用lua的返回值作为http请求的响应
# conf/ajax.lua为相对站点根目录的路径
content_by_lua_file conf/ajax.lua;
}
}
}
2.3 conf/ajax.lua
-- https://github.com/pintsized/lua-resty-http
local http = require 'resty.http'
-- https://github.com/rxi/json.lua
local json = require 'resty.json'
-- nginx location配置中set的$redirect_url变量
local redirect_url = ngx.var.redirect_url
-- 获取http请求类型
local request_method = ngx.var.request_method
-- 获取请求头中的cookie信息
local headers = ngx.req.get_headers()
local cookie = headers.cookie
-- 将所有与请求相关的信息放到body变量中,统一转发
local body = {
-- 获取请求uri,不包含查询参数
url = ngx.var.uri,
-- 获取请求参数
query = ngx.req.get_uri_args(),
-- http请求类型
type = request_method,
-- post的请求体
post = nil
}
-- 如果是post请求,则读取请求体,加入body变量中
if "POST" == request_method then
ngx.req.read_body()
body.post = ngx.req.get_post_args()
end
-- 重新发起http请求
local httpc = http:new()
local res, err = httpc:request_uri(redirect_url, {
method = 'POST',
-- 将body编码为json格式
body = json.encode(body),
headers = {
["Content-Type"] = "application/json",
-- 携带cookie发起请求,避免cookie或session丢失
Cookie = cookie
}
})
-- 返回响应体
ngx.say(res.body)
3. 启动
在站点根目录下,运行,
$ nginx -p `pwd`/ -c conf/nginx.conf
如果nginx已经启动了,则需要重新加载配置文件,
$ nginx -s reload
参考
OpenResty
Github: pintsized/lua-resty-http
Github: rxi/json.lua
网友评论