美文网首页
nginx中使用lua脚本

nginx中使用lua脚本

作者: dark68 | 来源:发表于2021-05-02 10:02 被阅读0次

lua模块的安装详见:https://www.jianshu.com/p/077208fc838c

1 Lua基本语法-变量的定义

以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上0个或多个字母,下划线,数字(0到9)。最好不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的。

Lua 不允许使用特殊字符如 @, $, 和 % 来定义标示符。 Lua 是一个区分大小写的编程语言。因此在 Lua 中 W3c 与 w3c 是两个不同的标示符。
关键字不允许做变量名称


关键字

2 Lua基本语法-数据类型

Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。


数据类型

我们可以使用type函数测试给定变量或者值的类型:

print(type("Hello world")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type(type(X))) --> string

变量
变量在使用前,必须在代码中进行声明,即创建该变量。编译程序执行代码之前编译器需要知道如何给语
句变量开辟存储区,用于存储变量的值。
Lua 变量有三种类型:全局变量、局部变量、表中的域。
函数外的变量默认为全局变量,除非用 local 显示声明。函数内变量与函数的参数默认为局部变量。
局部变量的作用域为从声明位置开始到所在语句块结束(或者是直到下一个同名局部变量的声明)。
变量的默认值均为 nil。

a = 5 -- 全局变量
local b = 5 -- 局部变量
function joke()
      c = 5 -- 全局变量
      local d = 6 -- 局部变量
end
joke()
print(c,d) --> 5 nil
do
      local a = 6 -- 局部变量
      b = 6 -- 全局变量
      print(a,b); --> 6 6
end
print(a,b) --> 5 6

循环语法:

while

Lua 编程语言中 while 循环语句在判断条件为 true 时会重复执行循环体语句。
Lua 编程语言中 while 循环语法:

while(condition)
do
     statements
end

使用如下:

a=10
while( a < 20 )
do
      print("a 的值为:", a)
      a = a+1
end

for循环

Lua 编程语言中 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。
Lua 编程语言中 for语句有两大类::
数值for循环
泛型for循环
数值for循环:Lua 编程语言中数值for循环语法格式:

for var=exp1,exp2,exp3 do
<执行体>
end

var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。

# 10 8 6 4 2 0
for i=10,0,-2 do
    print(i)
end

# 1 a 2 b 3 b
arr = {"a","b","c"}
for i,v in ipairs(arr) do
     #key
     print(i)
     #value
     print(v)
end

泛型for循环:泛型for循环通过一个迭代器函数来遍历所有值,类似java中的foreach语句。

--打印数组a的所有值
for i,v in ipairs(a)
      do print(v)
end

i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组。

days = {"Suanday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
for i,v in ipairs(days) do
    print(v)
end

输出结果:


流程控制
Lua 编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码,在条件为 false 时执行其他指定代码。
控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,true 和非nil为真。
要注意的是Lua中 0 为 true:
--[ 0 为true ]
if(0)
then
    print("0 为真")
end

3 nginx使用lua脚本

1.缓存
语法:lua_code_cache on | off
含义:指定是否开启lua的代码编译缓存,开发时可以设置为 off,以便lua文件实时生效,如果是生产线上,为了性能,建议开启。
2.路径
语法:lua_package_path
含义:设置 lua 代码的寻找目录。
3.ngx.var.VAR_NAME
语法:ngx.var.VAR_NAME
含义:读写Nginx的变量值。例如HTTP请求头、Nginx set的变量、URL参数,甚至Nginx通过正则表达式捕获的1、2等值(获取方式是ngx.var[1]、ngx.var[2],依此类推)。
案例:

server
{
    listen 8080;
    server_name www.blog131.com;
    root /www/blog;
    index  index.html index.htm;

    location /lus {
        default_type text/html;
        set $a '';
        set $b '';
        set $c '';
        #引入函数库
        #arg_test 是test参数
        rewrite_by_lua_block {
            local ngx = require "ngx";
            ngx.var.a = 1;
            ngx.var.b = ngx.var.http_user_agent;
            ngx.var.c = ngx.var.arg_test;
        }

        echo $a;
        echo $b;
        echo $c;
    }
}
test
请求头

4.Ngx.req.set_header()
语法:Ngx.req.set_header(header_name,header_value)
含义:添加或修改当前HTTP的请求头,如果请求头已经存在,则会被替换成新的值。通过此方式设置的请求头会被继承到子请求中。
5.Ngx.req.get_headers()
语法:ngx.req.get_headers()
含义:获取当前请求的全部请求头,并返回一个Lua的table类型的数据。
6.ngx.req.clear_header()
语法:ngx.req.clear_header(header_name)
含义:清除当前请求中指定的请求头。清除后,如果存在未执行的子请求,则子请求会继承清除后的请求头。

location /lus_header {
        default_type text/html;
        #引入函数库
        rewrite_by_lua_block {
            local ngx = require "ngx";
            ngx.req.set_header("Test",{"1","2"});
            local header_ngx = ngx.req.get_headers();
            ngx.say(header_ngx["Test"]);
            ngx.print(header_ngx["Test"]);
        }
    }
image.png
响应头

7.ngx.resp.get_headers
语法:ngx.resp.get_headers()
含义:读取当前请求的响应头,并返回一个Lua的table类型的数据。
8.ngx.header.HEADER = VALUE
语法:value = ngx.header.HEADER
含义:对响应头进行修改、清除、添加等操作。
如果需要清除一个响应头,将它赋值为nil即可,如下所示:
Ngx.header[“X-Test”] = nil

location /lus_resp {
        default_type text/html;
        #引入函数库
        content_by_lua_block {
            local ngx = require "ngx";
            ngx.header.test = {"1","2"};
            local header_ngx = ngx.resp.get_headers();
            ngx.say(header_ngx["Test"]);
        }
    }
image.png

9.set_by_lua
语法:set_by_lua $res <lua-script-str> [$arg1 $arg2 ...]
含义:是为了能够让nginx的变量与lua的变量相互作用赋值。

案例(注意引号):

    location /lus_set {
        default_type text/html;
        set $diff '';
        set_by_lua $sum '
            local ngx = require "ngx"
            local a = 32
            local b = 56
            ngx.var.diff = a - b
            return a + b';
        echo "sum = $sum, diff = $diff";
    }
image.png
10.content_by_lua
语法:content_by_lua <lua-script-str>
含义:可以由lua直接确定nginx响应页面的正文

案例:
content_by_lua “ngx.print(ngx.var[‘arg_a’])”

11.rewrite_by_lua
语法:rewrite_by_lua <lua-script-str>
含义:这个指令更多的是为了替代HttpRewriteModule的rewrite指令来使用的,优先级低于rewrite指令

案例 (重定向):

    location /lus_rewrite {
        set $a 12;
        set $b '';
        rewrite_by_lua '
            ngx.var.b = tonumber(ngx.var.a) + 1
            if tonumber(ngx.var.b) == 13 then
                return ngx.redirect("/bar");
            end
        ';
        echo "res = $b";

    }

相关文章

网友评论

      本文标题:nginx中使用lua脚本

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