IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> nginx+lua实现文件上传总结(亲测可用) -> 正文阅读

[PHP知识库]nginx+lua实现文件上传总结(亲测可用)

一、需求说明

前端经常需要增加一些模板jpg,然后重新发到生产;因此增加了一个功能,让用户自己上传模板jpg到前端服务器上。
前端项目位于前端服务器,有nginx;为了实现功能,再装一个jdk+java后台代码实现感觉不太合适,因此使用nginx+lua实现文件上传功能。

二、具体流程

1.访问前端服务器,例如http://10.123.123.123,此时出现的是nginx的欢迎页面,如果是Welcome to OpenResty,说明安装的是resty(这个软件包含nginx功能),那么环境基本是可以的;如果安装的是普通的nginx,那么可能需要重装为openresty。

2.修改resty(nginx)的配置信息,例如/home/appadmin/nginx/conf/nginx.conf,增加一个上传文件用的路径,样例如下:

location /uploadFile {
  error_log logs/upload.err.log;
  #if ($remote_addr !~* "^10\.13(0|3)\.(.*)\.(.*)$") { echo "ip wrong!"; }
  #set $home_path "/home/appadmin/uploadFile";
  #set $sub_path $head_sub_path;
  #lua_code_cache off;
  content_by_lua_file conf/luascript/upfile.lua;
}

说明:
(1)注释的home_path的意思是,可以把文件上传后保存的路径配置在这里,后续lua文件取这里的值即可。
(2)注释的sub_path的意思是,可以从请求头head_sub_path中读取一个路径(前端设置的),然后用这个变量拼接上传文件保存的二级路径即可。
(3)最后一句就是连接到upfile.lua,进行后续处理。

3.创建一个upfile.lua,放到指定位置,例如/home/appadmin/nginx/conf/luascript/upfile.lua,文件内容如下:

local upload = require "resty.upload"
local cjson = require "cjson"

local chunk_size = 4096
local form, err = upload:new(chunk_size)
if not form then
  ngx.log(ngx.ERR, "failed to new upload: ",err)
  ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end

form:set_timeout(1000)

string.split = function(s,p)
  local rt = {}
  string.gsub(s,'[^'..p..']+', function(w) table.insert(rt, w) end)
  return rt
end

-- FILE LOCATION
local saveRootPath = "/home/appadmin/uploadFile/"

local fileToSave

local ret_save = false

while true do
  local typ, res, err = form:read()
  if not typ then
    ngx.say("failed to read: ", err)
    return
  end

  if typ == "header" then
    -- read fileName from header
    local key = res[1]
    local value = res[2]
    if key == "Content-Disposition" then
      -- form-data; name="testFileName"; filename="testfile.txt"
      local kvlist = string.split(value,';')
      for _, kv in ipairs(kvlist) do
        local seg = string.trim(kv)
          if seg:find("filename") then
            local kvfile = string.split(seg, "=")
            local filename = string.sub(kvfile[2], 2, -2)
           if filename then
             fileToSave = io.open(saveRootPath .. filename, "w+")
           if not fileToSave then
             ngx.say("failed to open file ", filename)
             return
          end
          break
         end
        end
       end
      end
  else if typ == "body" then
    if fileToSave then
      fileToSave:write(res)
    end
  else if typ == "part_end" then
    if fileToSave then
        fileToSave:close()
        fileToSave = nil
    end

  ret_save = true
  elseif typ == "eof" then
    break
  else
    ngx.log(ngx.INFO, "do other things")
  end
end

if ret_save then
  ngx.say("save file ok")
end


4.创建一个html文件测试,例如放到/home/appadmin/nginx/html/myupload.html,内容如下:

<!DOCTYPE html>
<html>
<head>
<title>File Upload</title>
</head>

<body>
<form action="uploadFile" method="post" enctype="multipart/form-data">
<label for="testFileName">select file: </label>
<input type="file" name="testFileName" />
<input type="submit" name="upload" value="Upload" />
</form>
</body>
</html>

如果写在本地,action可以写成:

action="http://10.123.123.123/uploadFile"

直接访问nginx所在的那个路径。

5.如果测试成功,会有返回文件,内容为save file ok,正是lua文件中配置的,然后在服务器对应路径就可以看到上传的文件了,到此结束;

如果报错,继续向下看。

6.如果发现upload.err.log文件中有上传文件后的报错信息(上方nginx配置的):

(1)如果报错找不到resty.upload,解决方法如下:
使用find命令,查找有没有upload.lua文件;
如果有,则把这个文件复制到报错信息中提示的路径下;
(报错第一句会提示某个路径下没有找到upload.lua文件);

如果没有upload.lua文件,则需要安装,例如lua-resty-upload-0.10,安装方法参考下方或百度。

(2)如果报错找不到cjson/cjson.lua/cjson.so,解决方法如下:
可以安装lua-cjson-2.1.0.6

1.)先用find命令查看有没有cjson,因为如果安装的是resty版nginx的话,可能在[/home/appamin/nginx-1.13.6.2/build/bundle/lua-cjson-2.1.0.6]下已经有文件了,cd到这个路径即可。
1.5.)从网上下载这个tar.gz包,解压后cd到该路径下。
2.)vi Makefile,可以修改其中的安装路径;因为安装到默认路径可能会没有权限,所以修改:

#PREFIX = /usr/local
PREFIX = $(HOME)/lua

保存后退出vi。
3.)执行make命令(会读取Makefile文件并编译);如果报错找不到lua.h文件,则需要安装lua,例如LuaJIT-2.1-20180420,安装后用find找到该文件,复制到报错信息提示的路径下(如果安装时没有权限,同样修改安装路径即可);重新执行make命令。

4.)执行make install命令,安装成功后,就可以找到cjson.so文件了。

5.)把cjson.so复制到错误信息中提示找不到cjson.so的路径下即可。(不用管cjson/cjson.lua了,有cjson.so就可以了)

7.再次测试上传功能,应该可以成功了。

(如果还有哪些报错,可以留言,一起探讨解决)

三、总结

1.nginx应该选用openresty版本的。
2.修改nginx.conf,增加一个路径。
3.编写lua文件,用于实现文件上传。
4.编写前端html,用于自测。

5.文件删除功能也可以用nginx+lua实现,主要就是要写好lua,待后续研究。

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:17:00  更:2021-09-04 17:18:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:48:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码