使用 Nginx Upload Module 實現上傳文件功能

jopen 9年前發布 | 112K 次閱讀 Nginx Web服務器

普通網站在實現文件上傳功能的時候,一般是使用Python,Java等后端程序實現,比較麻煩。Nginx有一個Upload模塊,可以非常簡單的實現文件上傳功能。此模塊的原理是先把用戶上傳的文件保存到臨時文件,然后在交由后臺頁面處理,并且把文件的原名,上傳后的名稱,文件類型,文件大小set到頁面。下面和大家具體介紹一下。

一、編譯安裝Nginx

為了使用Nginx Upload Module,需要編譯安裝Nginx,將upload module編譯進去。upload module的代碼可以去Github上下載: Upload Module

之后的編譯安裝Nginx這里就不介紹,不了解的可以參考: Ubuntu 14.10下源碼編譯安裝Nginx 1.8.0

二、Nginx配置

Nginx upload module的簡單配置如下:

server {
    listen *:80 default_server;
    server_name 192.168.1.251;
    client_max_body_size 20m;
    client_body_buffer_size 512k;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE_ADD $remote_addr;
    location /upload {

# 轉到后臺處理URL,表示Nginx接收完上傳的文件后,然后交給后端處理的地址
upload_pass @python;
# 臨時保存路徑, 可以使用散列
# 上傳模塊接收到的文件臨時存放的路徑, 1 表示方式,該方式是需要在/tmp/nginx_upload下創建以0到9為目錄名稱的目錄,上傳時候會進行一個散列處理。
upload_store /tmp/nginx_upload;
# 上傳文件的權限,rw表示讀寫 r只讀
upload_store_access user:rw group:rw all:rw;
set $upload_field_name "file";
# upload_resumable on;
# 這里寫入http報頭,pass到后臺頁面后能獲取這里set的報頭字段
upload_set_form_field "${upload_field_name}_name" $upload_file_name;
upload_set_form_field "${upload_field_name}_content_type" $upload_content_type;
upload_set_form_field "${upload_field_name}_path" $upload_tmp_path;
# Upload模塊自動生成的一些信息,如文件大小與文件md5值
upload_aggregate_form_field "${upload_field_name}_md5" $upload_file_md5;
upload_aggregate_form_field "${upload_field_name}_size" $upload_file_size;
# 允許的字段,允許全部可以 "^.*$"
upload_pass_form_field "^.*$";
# upload_pass_form_field "^submit$|^description$";
# 每秒字節速度控制,0表示不受控制,默認0, 128K
upload_limit_rate 0;
# 如果pass頁面是以下狀態碼,就刪除此次上傳的臨時文件
upload_cleanup 400 404 499 500-505;
# 打開開關,意思就是把前端腳本請求的參數會傳給后端的腳本語言,比如:http://192.168.1.251:9000/upload/?k=23,后臺可以通過POST['k']來訪問。
upload_pass_args on;  
}
location @python {
proxy_pass http://localhost:9999;
# return 200;  # 如果不需要后端程序處理,直接返回200即可
}

}</pre>

三、后端處理程序

這里我們使用Django作為后端處理程序,比較簡單,具體如下:

首先創建Django項目:

django-admin.py startproject uploadmodule

然后,創建views.py文件,代碼如下:

# -- coding: utf-8 --
import os
import json
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
UPLOAD_FILE_PATH = '/tmp/nginx_upload/'
@csrf_exempt
def upload(request):
    request_params = request.POST
    file_name = request_params['file_name']
    file_content_type = request_params['file_content_type']
    file_md5 = request_params['file_md5']
    file_path = request_params['file_path']
    file_size = request_params['file_size']
    ip_address = request.META.get('HTTP_X_REAL_IP') or request.META.get('HTTP_REMOTE_ADD')

# save file to tmp
new_file_name = '%s_%s' % (file_md5, ip_address)
new_file_path = ''.join([UPLOAD_FILE_PATH, new_file_name, os.path.splitext(file_name)[-1]])
with open(new_file_path, 'a') as new_file:
    with open(file_path, 'rb') as f:
        new_file.write(f.read())
content = json.dumps({
    'name': file_name,
    'content_type': file_content_type,
    'md5': file_md5,
    'path': file_path,
    'size': file_size,
    'ip': ip_address,
})
response = HttpResponse(content, content_type='application/json; charset=utf-8')
return response</pre> <h4>四、示例 </h4>

上面的代碼完成之后,我們通過下面的命令啟動Django后端程序:

cd uploadmodule/
python manage.py runserver 0.0.0.0:9999

然后,模擬POST請求:http://192.168.1.251/upload/,上傳一個jpg文件,返回結果如下:

{
    "name": "6125444419718417450.jpg",
    "ip": "192.168.1.121",
    "content_type": "image/jpeg",
    "path": "/tmp/nginx_upload/0000000002",
    "md5": "c3b1bd2e72694a8d5fc4548b9ecd9e18",
    "size": "37980"
}

參考:

Ubuntu 14.10下源碼編譯安裝Nginx 1.8.0

HttpUploadModule - Nginx Community

vkholodkov/nginx-upload-module at 2.2

Uploading to nginx using the nginx upload module with php_handler

Over!

原文 http://xianglong.me/article/use-nginx-upload-module-to-implement-uploadi

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!