httpc库基于cf框架都内部实现的socket编写的http client库.
httpc库内置SSL支持, 在不使用代理的情况下就可以请求第三方接口.
httpc支持header、args、body、timeout请求设置, 完美支持各种httpc调用方式.
API介绍
httpc库使用前需要手动导入httpc库: local httpc = require "httpc"
.
httpc.get(domain, HEADER, ARGS, TIMEOUT)
调用get方法将会对domain发起一次HTTP GET请求.
domain是一个符合URL定义规范的字符串;
HEADER是一个key-value数组, 一般用于添加自定义头部;
ARGS为请求参数的key-value数组, 对于GET方法将会自动格式化为:args[n][1]=args[n][2]&args[n+1][1]=args[n+1][2]
;
TIMEOUT为httpc请求的最大超时时间;
httpc.post(domain, HEADER, BODY, TIMEOUT)
调用post方法将会对domain发起一次HTTP POST请求, 此方法的content-type
会被设置为:application/x-www-form-urlencoded
.
domain是一个符合URL定义规范的字符串;
HEADER是一个key-value数组, 一般用于添加自定义头部; 不支持Content-Type与Content-Length设置;
BODY是一个key-value数组, 对于POST方法将会自动格式化为:body[n][1]=body[n][2]&body[n+1][1]=body[n+1][2]
;
TIMEOUT为httpc请求的最大超时时间;
httpc.json(domain, HEADER, JSON, TIMEOUT)
json方法将会对domain发起一次http POST请求. 此方法的content-type
会被设置为:application/json
.
HEADER是一个key-value数组, 一般用于添加自定义头部; 不支持Content-Type与Content-Length设置;
JSON必须是一个字符串类型;
TIMEOUT为httpc请求的最大超时时间;
httpc.file(domain, HEADER, FILES, TIMEOUT)
file方法将会对domain发起一次http POST请求.
HEADER是一个key-value数组, 一般用于添加自定义头部; 不支持Content-Type与Content-Length设置;
FILES是一个key-value数组, 每个item包含: name(名称), filename(文件名), file(文件内容), type(文件类型)等属性. 文件类型可选.
TIMEOUT为httpc请求的最大超时时间;
httpc 返回值
所有httpc请求接口均会有2个返回值: code
, response
. code为http协议状态码, response为回应body(字符串类型).
参数不正确, 连接被断开等其它错误, code将会为nil, response为错误信息.
“一次性HTTP请求”
什么是一次性httpc请求呢?
每次我们使用httpc库在请求第三方http接口的时候, 都会在接口返回后关闭连接. 这在日常使用中一边也没什么问题.
但是当我们需要多次请求同一个接口的时候, 每次请求完毕就关闭连接显然不是那么高效, 现在我们尝试使用一个http class对象来解决这个问题.
注意: httpc class对象不能对不同域名的接口使用同一个连接, 这会返回一个错误调用给使用者.
httpc库的class对象使用介绍
要使用httpc的class
需要导入httpc的class库, 导入方式为: local httpc = require "httpc.class"
.
当需要使用httpc发起请求之前, 需要先创建一个httpc的对象, 如: local hc = httpc:new {}
. httpc对象创建与初始化完毕后, 使用方式同上述API所示.
hc
与httpc
拥有相同的API, 但是需要使用不同的调用方式. 如: hc:get
、hc:post
、hc:json
、hc:file
.
一旦hc
使用完毕时, 需要显示的调用hc:close()
方法来关闭创建的httpc对象并销毁httpc的连接.
开始实践
现在, 让我们将上面学到的API使用方式运用到实践中.
1. 启动一个httpd库的web server
在main.lua
中启动一个httpd
的server.
local httpd = require "httpd"
local json = require "json"
local app = httpd:new("httpd")
app:listen("", 8080)
app:run()
1. 增加一个API路由用于ip地址归属地查询
我们先利用httpd
库启动一个server服务, 并且对外提供IP归属地查询接口
app:api('/ip', function(content)
local httpc = require "httpc"
local args = content.args
if not args or not args['ip'] then
return json.encode({
code = 400,
msg = "错误的接口调用方式",
data = json.null,
})
end
local code, response = httpc.get("http://freeapi.ipip.net/"..args["ip"])
if code ~= 200 then
return json.encode({
code = 401,
msg = "获取数据失败",
data = json.null,
})
end
return response
end)
现在代码已经完成! 让我们打开浏览器输入:http://localhost:8090/ip?ip=8.8.8.8
查看返回数据.
2. 查询多个IP地址的归属地
一个请求对应一次回是HTTP协议的本质! 但是我们经常会遇到批量请求的业务场景, 我们就以此来设计一个批量请求/返回的例子.
让我们假设客户端将会发送一次POST请求, body为json类型并且里面包含一个IP数组: ip_list = {1.1.1.1, 8.8.8.8, 114.114.114.114}.
服务端在接受到这个数组之后, 需要将这ip的归属地信息一次性返回给客户端.
app:api('/ips', function(content)