数字化技能提升教程,数字化时代生存宝典

OpenResty Lua 脚本入门:读取参数、请求头与返回响应

浏览:730

OpenResty 可以在 Nginx 的请求处理过程中执行 Lua 脚本,实现参数读取、请求头检查和自定义响应。下面从 Hello World 开始,依次介绍 URL 参数、Header、状态码、独立 Lua 文件和调试日志的基本用法。

以下示例以已安装并启动的 OpenResty 为前提,安装目录为 /usr/local/openresty。各个 location 配置需要放在 nginx.conf 的 server 块内;如果已有相同的 location,应修改原配置,避免重复定义。

一、输出 Hello World

在 server 块中添加以下配置,让 OpenResty 在访问根路径时执行 Lua 脚本:

location / {
    default_type text/plain;

content_by_lua_block {
ngx.say("Hello, OpenResty")
}
}

其中,default_type text/plain 将响应类型设置为纯文本,content_by_lua_block 用于编写生成响应内容的 Lua 代码,ngx.say() 用于输出内容并添加换行。

保存配置后,先检查语法,再重新加载:

sudo /usr/local/openresty/nginx/sbin/nginx -t
sudo /usr/local/openresty/nginx/sbin/nginx -s reload

语法检查通过后再执行重载。后续修改 Nginx 配置时,也需要执行这两条命令。

测试访问:

curl http://127.0.0.1/

预期返回:

Hello, OpenResty

二、读取 URL 参数

通过 ngx.req.get_uri_args() 可以读取 URL 中的查询参数。例如,读取 name 参数并返回问候语:

location /hello {
    default_type text/plain;

content_by_lua_block {
local args = ngx.req.get_uri_args()
local name = args["name"]

if type(name) ~= "string" then
name = "OpenResty"
end

ngx.say("Hello, " .. name)
}
}

Lua 使用 .. 拼接字符串。这里增加类型判断,是因为只有参数名或重复传入同名参数时,读取结果可能是布尔值或表,不能直接当作字符串拼接。

检查并重载配置后,执行:

curl "http://127.0.0.1/hello?name=Tom"

预期返回:

Hello, Tom

不传入 name 参数时:

curl http://127.0.0.1/hello

预期返回:

Hello, OpenResty

三、读取 Header

通过 ngx.req.get_headers() 可以获取请求头。下面以读取自定义请求头 X-Token 为例:

location /header {
    default_type text/plain;

content_by_lua_block {
local headers = ngx.req.get_headers()
local token = headers["X-Token"]

ngx.say(token or "no token")
}
}

检查并重载配置后,携带请求头进行测试:

curl -H "X-Token: test-token" http://127.0.0.1/header

预期返回:

test-token

未传入 X-Token 时,返回 no token。

此示例仅用于演示请求头读取,实际业务中不要将真实的认证令牌直接返回给客户端。

四、根据条件返回状态码

读取请求头后,可以根据 Token 是否符合要求返回不同的 HTTP 状态码。下面使用独立的 /auth 路径演示:

location /auth {
    default_type text/plain;

content_by_lua_block {
local headers = ngx.req.get_headers()
local token = headers["X-Token"]

if token ~= "123456" then
ngx.status = 401
ngx.say("Unauthorized")
return
end

ngx.say("Authorized")
}
}

当 Token 缺失或不匹配时,返回 401 Unauthorized;匹配时返回 200 和 Authorized。

状态码应在 ngx.say() 输出响应内容之前设置,避免响应头已经发送后无法修改。

检查并重载配置后,分别测试:

curl -i http://127.0.0.1/auth
curl -i -H "X-Token: 123456" http://127.0.0.1/auth

-i 可以同时显示响应头和正文,便于确认 HTTP 状态码。这里的 123456 仅为演示值,生产环境应使用实际的身份验证机制。

五、使用单独的 Lua 文件

当脚本内容增加时,可以将 Lua 代码保存到独立文件中,方便维护。

先创建目录和文件:

sudo mkdir -p /usr/local/openresty/nginx/lua
sudo vi /usr/local/openresty/nginx/lua/index.lua

在 index.lua 中写入:

ngx.say("Hello from index.lua")

然后在 nginx.conf 的 server 块中引用该文件:

location /lua {
    default_type text/plain;
    content_by_lua_file /usr/local/openresty/nginx/lua/index.lua;
}

确保 OpenResty 工作进程具有读取该文件的权限。检查并重载配置后,执行:

curl http://127.0.0.1/lua

预期返回:

Hello from index.lua

默认启用 Lua 代码缓存时,修改独立 Lua 文件后也需要重新加载 OpenResty,才能让后续请求使用更新后的代码。

六、输出调试日志

通过 ngx.log() 可以将调试信息写入 OpenResty 的错误日志。例如,在 Lua 代码中加入:

ngx.log(ngx.ERR, "request uri: ", ngx.var.request_uri)

其中,ngx.ERR 表示错误级别,ngx.var.request_uri 表示原始请求 URI,包含路径和查询参数。

可以将它放在 index.lua 中:

ngx.log(ngx.ERR, "request uri: ", ngx.var.request_uri)
ngx.say("Hello from index.lua")

重新加载 OpenResty 并访问 /lua 后,查看日志:

sudo tail -f /usr/local/openresty/nginx/logs/error.log

日志实际位置以 error_log 配置为准。ngx.ERR 适合演示排查过程,日常调试可以使用 ngx.INFO,但需要确保日志配置允许记录该级别。

如果 URL 参数可能包含令牌等敏感信息,可仅记录不含查询参数的路径:

ngx.log(ngx.ERR, "request path: ", ngx.var.uri)

相关阅读:

《Nginx LuaJIT架构说明:OpenResty、Nginx与LuaJIT关系》

《Linux安装OpenResty教程:替代Nginx并支持Lua脚本》

相关文章
猜你喜欢