nginx-upload-module模块实现文件上传(multipart/form-data和断点续传)

前言

有时候我们想简单实现文件上传的功能,又不想使用额外的语言(比如PHP、Java),或者想实现文件的断点续传。这个时候Nginx的一个模块nginx-upload-module就能满足我们的需求。
模块安装

下载模块:

cd /tmp
wget https://codeload.github.com/vkholodkov/nginx-upload-module/zip/2.2
unzip 2.2

安装模块:

.configure --add-module=/tmp/nginx-upload-module-2.2/
multipart/form-data表单上传示例

nginx.conf配置:

server {
[...]
        location /upload {
                upload_pass @uploadHandler;
                upload_store /usr/local/nginx/upload_temp 1;
                upload_set_form_field $upload_field_name.path "$upload_tmp_path";
        }
 
        location @uploadHandler {
                proxy_pass http://backend-host;
        }
[...]
}

这里在server里定义了upload location,这个location是上传的接口,还有@uploadHandler location,是当文件上传完成后,nginx模块会对这个location发送一些必要的信息,如文件上传的路径。
这里涉及了几个指令:

upload_pass @uploadHandler: 上传完成后会发送必要的数据到@uploadHandler;
upload_store /usr/local/nginx/upload_temp 1: 文件上传的临时目录;
upload_set_form_field $upload_field_name.path “$upload_tmp_path”: 设置文件上传完成后,把文件临时路径发送给upload_pass指定的location。

断点续传示例

nginx.conf配置

server {
[...]
        location /resumable_upload {
                upload_resumable on;
                upload_state_store /usr/local/nginx/upload_temp ;
                upload_pass @drivers_upload_handler;
                upload_store /usr/local/nginx/upload_temp;
                upload_set_form_field $upload_field_name.path "$upload_tmp_path";
        }
 
        location @resumable_upload_handler {
                proxy_pass http://localhost:8002;
        }
[...]
}

与上一步multipart/form-data表单上传示例配置不同的地方有:
upload_resumable on: 开启断点续传功能;
upload_state_store /usr/local/nginx/upload_temp: 设置断点续传状态文件存储的目录。

上传文件第一个片段

POST /upload HTTP/1.1
Host: example.com
Content-Length: 51201
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="big.TXT"
X-Content-Range: bytes 0-51200/511920
Session-ID: 1111215056
 
<0-51200的字节文件数据>

上传文件第一个片段服务器响应
HTTP/1.1 201 Created
Date: Thu, 02 Sep 2010 12:54:40 GMT
Content-Length: 14
Connection: close
Range: 0-51200/511920
 
0-51200/511920

上传文件最后一个片段
POST /upload HTTP/1.1
Host: example.com
Content-Length: 51111
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="big.TXT"
X-Content-Range: bytes 460809-511919/511920
Session-ID: 1111215056
 
<460809-511919字节文件数据>

上传文件最后一个片段服务器响应
HTTP/1.1 200 OK
Date: Thu, 02 Sep 2010 12:54:43 GMT
Content-Type: text/html
Connection: close
Content-Length: 2270
 
<响应的内容>

请求头说明
请求头  说明
Content-Disposition attachment, filename=“上传的文件名”
Content-Type  待上传文件的mime type,如application/octet-stream(注:不能为multipart/form-data)
X-Content-Range  待上传文件字节范围,如第一片段bytes 0-51200/511920,最后一个片段bytes 460809-511919/511920(注:文件第一个字节标号为0,最后一个字节标号为n-1,其中n为文件字节大小)
X-Session-ID 上传文件的标识,由客户端随机指定.因为是断点续传,客户端必须确保同一个文件的所有片段上传标识一致

Content-Length 上传片段的大小

Python上传demon
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
 
import os.path
import requests
import hashlib
 
# 待上传文件路径
FILE_UPLOAD = "/tmp/testfile"
# 上传接口地址
UPLOAD_URL = "http://host/drivers_upload"
# 单个片段上传的字节数
SEGMENT_SIZE = 1048576
 
def upload(fp, file_pos, size, file_size):
    session_id = get_session_id()
    fp.seek(file_pos)
    payload = fp.read(size)
    content_range = "bytes {file_pos}-{pos_end}/{file_size}".format(file_pos=file_pos,
                    pos_end=file_pos+size-1,file_size=file_size)
    headers = {'Content-Disposition': 'attachment; filename="big.TXT"','Content-Type': 'application/octet-stream',
                'X-Content-Range':content_range,'Session-ID': session_id,'Content-Length': size}
    res = requests.post(UPLOAD_URL, data=payload, headers=headers)
    print(res.text)
 
 
# 根据文件名hash获得session id
def get_session_id():
    m = hashlib.md5()
    file_name = os.path.basename(FILE_UPLOAD)
    m.update(file_name)
    return m.hexdigest()
 
def main():
    file_pos = 0
    file_size = os.path.getsize(FILE_UPLOAD)
    fp = open(FILE_UPLOAD,"r")
 
    while True:
        if file_pos + SEGMENT_SIZE >= file_size:
            upload(fp, file_pos, file_size - file_pos, file_size)
            fp.close()
            break
        else:
            upload(fp, file_pos, SEGMENT_SIZE, file_size)
            file_pos = file_pos + SEGMENT_SIZE
 
if __name__ == "__main__":
    main()

时间: 2024-10-16 14:05:01

nginx-upload-module模块实现文件上传(multipart/form-data和断点续传)的相关文章

PHP利用APC模块实现文件上传进度条的方法_php技巧

本文实例讲述了PHP利用APC模块实现文件上传进度条的方法.分享给大家供大家参考.具体分析如下: 以前的php5.2之前的版本是不能可使用APC模块的,因为之前的压根就没有这个APC模块,如果想使用APC模块实现上传进度条我们必须是php5.2或更高版本. 从5.2开始APC加入了一个叫APC_UPLOAD_PROGRESS的东东,解决了困扰大家已久的进度条问题.并且它把原来的上传时把临时文件全部缓存到内存改成了当临时文件达到设定值时就自动保存到硬盘,有效地改善了内存利用状况. 它的作用原理是在

linux+nginx+mysql+php系统修改文件上传大小限制

PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir.upload_max_filesize.post_max_size等参数,Nginx中则是client_max_body_size. 1. 修改php配置文件(php.ini) ① file_uploads = On 默认允许HTTP文件上传,此选项必须设置为On. ② upload_tmp_dir = 默认为空 ③ upload_max_filesize = 2M 默认upload_max_filesize

PHP中利用APC模块实现文件上传进度条

从5.2开始APC加入了一个叫APC_UPLOAD_PROGRESS的东东,解决了困扰大家已久的进度条问题.并且它把原来的上传时把临时文件全部缓存到内存改成了当临时文件达到设定值时就自动保存到硬盘,有效地改善了内存利用状况. 它的作用原理是在上传时候赋予每个上传一个唯一的ID,当 PHP 脚本收到一个上传文件时,解释程序将自动检查 $_POST数组中名为 APC_UPLOAD_PROGRESS 的隐藏字段,它将成为缓存变量,存储关于上传的信息,这样脚本就可以通过上传的ID来访问上传文件的状态信息

用jQuery File Upload实现简单的文件上传

FORM中的代码: {# file_path #} <div class="form-group"> <label class="control-label col-md-3"> {{ form.file_path.label_tag }} {% for error in form.file_path.errors %} <span class="label label-danger">{{ error }}&

C# 通用文件上传模块该怎么写?想写个没思路

问题描述 最近要做个通用的上传模块把文件上传到服务器!但是上传服务器要服务的吧,一时之间没什么头绪.哪位大神能指点下啊小弟感激不尽啊 解决方案 本帖最后由 gongyq_627 于 2011-06-02 09:28:06 编辑解决方案二:但是上传服务器要服务的吧?不明白你的意思文件上传本没什么复杂的,想要比较好的效果可以考虑使用第三方插件,比如基于Jquery的js插件:Uploadify--解决方案三:usingSystem;usingSystem.Collections.Generic;us

jQuery File Upload文件上传插件使用详解_jquery

jQuery File Upload 是一个Jquery文件上传组件,支持多文件上传.取消.删除,上传前缩略图预览.列表显示图片大小,支持上传进度条显示:支持各种动态语言开发的服务器端. 官网链接:https://github.com/blueimp/jQuery-File-Upload/wiki 特点:拖放支持:上传进度条:图像预览:可定制和可扩展的:兼容任何服务器端应用平台(PHP, Python, Ruby on Rails, Java, Node.js, Go etc.). 使用方法:

nginx upload module的使用

现在的网站,总会有一点与用户交互的功能,例如允许用户上传头像,上传照片,上传附件这类的.PHP写的程序,对于上传文件效率不是很高.幸好,nginx有一个名为upload的module可以解决这个问题.网络上已经有很多关于upload module的文章,但是大部分都是介绍编译安装这些的,对于一些细节叙述不是很清楚,于是自己写了这篇.参考了很多其他人的文档,在此致谢,详细见参考文档部分. 一.upload module的工作原理nginx upload module模块通过nginx服务器来接受用

基于nodejs+express(4.x+)实现文件上传功能_node.js

Nodejs是一个年轻的编程框架,充满了活力和无限激情,一直都在保持着快速更新.基于Nodejs的官方Web开发库Express也在同步发展着,每年升级一个大版本,甚至对框架底层都做了大手术.在Express4时,替换掉中件间库connect,而改用多个更细粒度的库来取代.带来的好处是明显地,这些中间件能更自由的更新和发布,不会受到Express发布周期的影响:但问题也是很的棘手,不兼容于之前的版本,升级就意味着要修改代码. 通过一段时间的查阅资料.摸索,我发现实现上传的方式有:1.expres

JavaWeb 后端 &lt;十四&gt; 文件上传下载

1.文件上传与下载 案例:          注册表单/保存商品等相关模块!          --à 注册选择头像 / 商品图片          (数据库:存储图片路径 / 图片保存到服务器中指定的目录) 1.1 文件上传 文件上传,要点: 前台:          1. 提交方式:post          2. 表单中有文件上传的表单项: <input type="file" />          3. 指定表单类型:                    默认类