lua脚本的基础操作
-- 1、赋值运算
a,b = 10,20
print('a=',a,'b=',b)
-- 结果: a=10,b=20
c,d,e = 1,2
print('c=',c,'d=',d,'e=',e)
-- 结果: c=1,d=2,e=nil 注意不赋值默认为nil
x,y,z = 4,5,6
print("x=",x,"y=",y)
-- 结果 x= 4 y= 5
-- 2、关系运算
e,f = 1,2
print(e + f) --3
print(e / f) --0.5
print(e * f) --2
print(e % f) --1
print(e ^ f) -- 1 (^表示次方)
print(-e) -- -1 (取负数)
-- 3、关系运算符
A,B = true,false
print(A and B) -- false 与
print(A or B) -- true 或
print(not(A and B)) --true 非
-- 4、其他运算符
print("hello".."-".."world") -- ..表示lua中字符串的连接
print(#"hello") --返回字符串hello的长度
-- 返回数组的长度
c = {1,2,3,4,5,6,7}
print(#c) -- 7
-- 5、lua流程控制
-- if
if (true) then
print("ok")
end
-- if的嵌套
c = 20
if(c > 10)
then
if(c < 30)
then
print("c".."的值在10到30之间")
end
end
-- while
k = 20
while(k > 0) do
print(k)
k = k - 1
end
-- 6、循环
-- for循环可以分为数值for循环和泛型for循环
-- 数值for循环
for i = 1, 10
do
print(i)
end
-- 下式中,2为每次循环所增加的步长
for i = 1, 10 ,2
do
print(i)
end
-- 当满足条件时,跳出循环。类似于java中的do while
n = 10
repeat
print(n)
n = n - 1
until (n < 1)
-- 泛型循环 k为索引 v为索引对应的值,ipairs是一个迭代函数
arr = {'a','b',3.14}
for k,v in ipairs(arr) do
print(k,v)
end
---- 效果
----1 a
----2 b
----3 3.14
arr = {1,2,3,4,5}
for k,v in pairs(arr) do
print(k,v)
end
-- pairs与ipairs的区别
-- pairs迭代table,可以遍历表中的所有的key可以返回null,能遍历集合的所有元素。即 pairs
-- 以遍历集合中所有的 key,并且除了迭代器本身以及遍历表本身还可以返回 nil。
-- ipairs 仅仅遍历值,按照索引升序遍历,索引中断停止遍历。
-- 迭代数组,不能返回 nil,如果遇到 nil 则退出
-- 7、数组 数组的大小不确定,数组的下标从1开始
arr = {"aaa","bbb","ccc"}
for i = 1,#arr -- #arr 数组的长度
do
print(arr[i])
end
-- 使用泛型for遍历数组
arr = {"aaa","bbb","ccc"}
for k,v in ipairs(arr) do print(k,v) end
-- 8、转字符串
-- toString() 可以使布尔类型和数值类型转换为字符串类型
-- 9、转换成数字
-- tonumber() 可以把非数字的原始值转换为数字
-- 9、函数
function func(a,b,c)
print(a,b,c)
return a+b+c
end
print(func(1,2,3))
-- 效果
-- 1 2 3 func中print打印
-- 6 调用函数打印
function func(a,b,c)
print(a,b,c)
return a+b+c
end
local x,y,z = func(1,2,3) -- 使用局部变量接收函数的返回值
print(x,y,z)
-- 结果 6 nil nil
-- 10、table 用于创建不同的数据类型,可以用任意类型的值作为索引,除了nil。
-- 不固定大小,可以动态的扩容
-- 应用:一般在脚本中,用table来配置相关信息
table1 = {name = '微光'}
table1.age = 24
table1.gender = 'm'
table1.address = 'SXYCPL'
print(table1['name']) -- key为字符串 调用时需要引起来
print(table1.age)
-- 应用 table中内置table
local params = {
{ip = "192.168.153.110"},
{ip = "192.168.153.111"},
{ip = "192.168.153.112"},
}
print(params[1]['ip']) -- params[1] 获取子table params[1]['ip'] 获取子table的值
OpenResty的入门练习
浏览器请求GET和POST的区别:
post和get在本质上是没有区别的,只不过在使用中进行了区别,下面主要说明的是使用中的区别
1、GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。
POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。上面的id=1213&name=suguniang就是两个实际的传输数据键值对。因此,GET请求的数据会暴露在地址栏中,而POST请求则不会。
2、传输数据的大小
在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。
对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。
3、安全性
POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET请求提交的数据还可能会造成Cross-site request frogery攻击,但是真正重要的数据在传的过程中还会更换协议http–https,比如在网上支付的过程中。
4、HTTP中的GET,POST,SOAP协议都是在HTTP上运行的。
5、GET和POST还有一个重大区别,简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
- GET与POST都有自己的语义,不能随便混用。
- 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
- 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
以上GET和POST请求的区别转载自浏览器中GET和POST请求的区别
lua脚本操作之获取uri参数
– 获取get请求参数
local arg = ngx.req.get_uri_args()
for k, v in pairs(arg) do
ngx.say("[GET] key:",k,“v:”,v)
end– 获取post请求参数
ngx.req.read_body() --解析post参数之前一定要先读取body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
ngx.say("[GET]key:",k,“v:”,v)
end
lua脚本操作之获取header
local hearders= ngx.req.get_headers()
for k,v in pairs(headers) do
ngx.say("[GET]key:",k,“v:”,v)
end
lua脚本操作之获取body
local data = ngx.req.get_body_data()
ngx.say(“data:”,data)
lua脚本连接Redis并操作添加数据到Redis
local r = require "resty.redis"
-- 获取redis实例
local redis = r:new()
-- 设置超时时间 单位为毫秒
redis:set_timeout(5000) -- 5sec
-- 获取连接
local ok,error = redis:connect("host","port")
if not ok then
ngx.say("failed to connect")
return
end
-- 若在redis.conf中配置了redis的密码,则需要添加下述代码
local count
count, err = redis :get_reused_times()
if 0 == count then
ok, err = redis :auth("密码")
if not ok then
ngx.say("failed to auth: ", err)
return
end
elseif err then
ngx.say("failed to get reused times: ", err)
return
end
-- 向redis中添加数据
ok,error = redis:set("fruit","apple")
if not ok then
ngx.say("fialed")
else
ngx.say("success")
end
-- 设置连接池大小 10 和最大的空闲时间
local ok,error = redis:set_keepalive(10000,100)
if not ok then
ngx.say("failed to set keepalive:",error)
end
需要注意的是: 以上编写的lua脚本,均需要上传至虚拟机上,同时修改 openresty/nginx/conf/nginx.conf中,lua脚本的地址
location / {
# root html;
# index index.html index.htm;
default_type text/html;
content_by_lua_file 此处写虚拟机上lua脚本的地址;
之后在 /openresty/nginx/sbin/ 下执行 ./nginx -s reload ,执行与redis交互的脚本时,相应的redis需要开启。
错误整理
执行lua2redis.lua 脚本时报错:
lua entry thread aborted: runtime error: /opt/apps/openresty/lualib/resty/redis.lua:238: bad argument #1 to 'rawget' (table expected, got string)
错误原因:
ok,error = redis:set("fruit","apple")
此处应该为 : 号,若写成 . 则会报上述错误。若为逗号,set的参数应该为 set(self,"fruit","apple")