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脚本》
-
广告合作
-
QQ群号:4114653



