美文网首页Other
[nginx] 使用lua统一转发nginx的get/post请

[nginx] 使用lua统一转发nginx的get/post请

作者: 何幻 | 来源:发表于2017-11-22 14:18 被阅读1641次

说明

使用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

相关文章

网友评论

    本文标题:[nginx] 使用lua统一转发nginx的get/post请

    本文链接:https://www.haomeiwen.com/subject/cgsnvxtx.html