OpenResty 使用 lua-resty-upload 上传文件
OpenResty Lua About 3,909 words说明
lua-resty-upload
内置于OpenResty
中,可直接require
即可。
Linux
平台文件保存路径需为绝对路径,不能使用相对路径。
Windows
平台上传的文件无法打开使用io.open
函数传入的模式为w+b
(b
:以二进制方式写入,避免不通平台换行符问题。Linux
下w+
即可,w+b
也同样适用),可参考之前文章:https://www.zhangbj.com/p/641.html
备注
对于反向代理的接口需设置Host
和X-Scheme
获取反向代理前的信息。
location /api/ {
proxy_connect_timeout 5; # 单位:秒
proxy_set_header Host $host; # 转发来源 host
proxy_set_header X-Scheme $scheme; # 转发来源 scheme
proxy_pass http://127.0.0.1:9527/;
}
示例代码
local json = require "cjson.safe"
local const = require "module.const"
local upload = require "resty.upload"
--local root_path = "z_blog_openresty/resources/img/" .. ngx.re.gsub(ngx.today(), "-", "") .. "/"
local relative_path = "uploads/img/"
-- ngx.var.realpath_root Windows输出:./html Linux输出:/usr/local/openresty/nginx/html
-- ngx.var.document_root Windows输出:./html Linux输出:/usr/local/openresty/nginx/html
--local root_path = "z_blog_openresty/resources/" .. relative_path 如果只用相对路径,Linux上将报错
local root_path = ngx.var.document_root .. "/../z_blog_openresty/resources/" .. relative_path
local chunk_size = 4096
local form = upload:new(chunk_size)
local file
local file_name
while true do
local typ, res, err = form:read()
if not typ then
ngx.log(ngx.ERR, "upload img failed to read#" .. err)
ngx.say(json.encode(const.fail("failed to read#" .. err)))
return
end
if typ == "header" then
-- res
-- ["Content-Disposition","form-data; name=\"image\"; filename=\"aa.aa.png\"","Content-Disposition: form-data; name=\"image\"; filename=\"aa.png\""]
-- 限制 image 字段
local param_info = ngx.re.match(res[2], [[form-data; name="(.+)";]])
-- {"0":"form-data; name=\"image\";","1":"image"}
if param_info then
local param = param_info[1]
if param ~= "image" then
ngx.log(ngx.ERR, "upload img invalid param#" .. param)
ngx.say(json.encode(const.fail("invalid param#" .. param)))
return
end
local file_info = ngx.re.match(res[2], [[filename="(.+)\.(.+)"]])
-- {"0":"filename=\"aa.aa.png\"","1":"aa.aa","2":"png"}
if file_info then
local file_extension = file_info[2]
local typ_match = ngx.re.match(file_extension, [[(png)|(jpeg)|(jpg)|(gif)|(svg)|(bmp)|(webp)]], "i")
if not typ_match then
ngx.log(ngx.ERR, "upload img file type error#" .. file_extension)
ngx.say(json.encode(const.fail("file type error#" .. file_extension)))
return
end
file_name = ngx.md5(ngx.now() .. ngx.var.pid .. file_info[1]) .. "." .. file_extension:lower()
file = io.open(root_path .. file_name, "w+b")
if not file then
ngx.log(ngx.ERR, "upload img failed to open file#" .. root_path .. file_name)
ngx.say(json.encode(const.fail("failed to open file#" .. file_name)))
return
end
end
end
elseif typ == "body" then
if file then
file:write(res)
end
elseif typ == "part_end" then
if file then
file:close()
file = nil
end
elseif typ == "eof" then
break
else
-- do nothing
end
end
if not file_name then
ngx.log(ngx.ERR, "upload img invalid file#" .. ngx.var.http_user_agent)
ngx.say(json.encode(const.fail("invalid file")))
return
end
--微信小程序中图片不支持直接斜杠+名称的格式 /aaa.jpg
--local file_url = string.format("/%s%s", relative_path, file_name)
--local file_url = string.format("%s://%s/%s%s", ngx.var.scheme, ngx.var.host, relative_path, file_name)
local file_url = string.format("%s://%s/%s%s", ngx.req.get_headers()['X-Scheme'], ngx.var.host, relative_path, file_name)
ngx.say(json.encode(const.ok(file_url)))
Views: 3,448 · Posted: 2021-03-02
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...