1. 程式人生 > 實用技巧 >nginx上傳

nginx上傳

一. nginx upload module原理

官方文件:http://www.grid.net.ru/nginx/upload.en.html

Nginx upload module通過nginx服務來接受使用者上傳的檔案,自動解析請求體中儲存的所有檔案上傳到upload_store指定的目錄下。這些檔案資訊從原始請求體中分離並根據nginx.conf中的配置重新組裝好上傳引數,交由upload_pass指定的段處理,從而允許處理任意上傳檔案。每個上傳檔案中的file欄位值被一系列的upload_set_form_field指令值替換。每個上傳檔案的內容可以從$upload_tmp_path變數讀取,或者可以將檔案轉移到目的目錄下。上傳的檔案移除可以通過upload_cleanup指令控制。如果請求的方法不是POST,模組將返回405錯誤(405 Not Allowed),該錯誤提示可以通過error_page指令處理。

具體的過程如下:

1. 使用者訪問能夠選擇上傳檔案的頁面

2. 使用者提交表單

3. 瀏覽器把檔案和有關檔案的資訊作為請求的一部分發送給伺服器

4. 伺服器把檔案儲存到臨時儲存目錄下upload_store

5. upload_pass指定的處理表單提交的php頁面將檔案從upload_store拷貝到持久儲存位置

二.nginx upload module配置引數

upload_pass 指明後續處理的php地址。檔案中的欄位將被分離和取代,包含必要的資訊處理上傳檔案。

upload_resumable 是否啟動可恢復上傳。

upload_store 指定上傳檔案存放地址(目錄)。目錄可以雜湊,在這種情況下,在nginx啟動前,所有的子目錄必須存在。

upload_state_store 指定儲存上傳檔案可恢復上傳的檔案狀態資訊目錄。目錄可以雜湊,在這種情況下,在nginx啟動前,所有的子目錄必須存在。

upload_store_access 上傳檔案的訪問許可權,user:r是指使用者可讀

upload_pass_form_field 從表單原樣轉到後端的引數,可以正則表示式表示。:

$upload_field_name -- 原始檔案中的欄位的名稱

upload_pass_form_field "^submit$|^description$";

意思是把submit,description這兩個欄位也原樣通過upload_pass傳遞到後端php處理。如果希望把所有的表單欄位都傳給後端可以用upload_pass_form_field "^.*$";

upload_set_form_field 名稱和值都可能包含以下特殊變數:

$upload_field_name 表單的name值

$upload_content_type 上傳檔案的型別

$upload_file_name 客戶端上傳的原始檔名稱

$upload_tmp_path 檔案上傳後儲存在服務端的位置

upload_aggregate_form_field 可以多使用的幾個變數,檔案接收完畢後生成的並傳遞到後端

$upload_file_md5 檔案的MD5校驗值

$upload_file_md5_uc 大寫字母表示的MD5校驗值

$upload_file_sha1 檔案的SHA1校驗值

$upload_file_sha1_uc 大寫字母表示的SHA1校驗值

$upload_file_crc32 16進製表示的檔案CRC32值

$upload_file_size 檔案大小

$upload_file_number 請求體中的檔案序號

這些欄位值是在檔案成功上傳後計算的。

upload_cleanup 如果出現400 404 499 500-505之類的錯誤,則刪除上傳的檔案

upload_buffer_size 上傳緩衝區大小

upload_max_part_header_len 指定頭部分最大長度位元組。

upload_max_file_size 指定上傳檔案最大大小,軟限制。client_max_body_size硬限制。

upload_limit_rate 上傳限速,如果設定為0則表示不限制。

upload_max_output_body_len 超過這個大小,將報403錯(Request entity too large)。

upload_tame_arrays 指定檔案欄位名的方括號是否刪除

upload_pass_args 是否轉發引數。

三. nginx配置

# wget http://www.nginx.org/download/nginx-1.2.2.tar.gz

# wget http://www.grid.net.ru/nginx/download/nginx_upload_module-2.2.0.tar.gz

# tar zxvf nginx_upload_module-2.2.0.tar.gz -c ../software/

# tar zxvf nginx_upload_module-2.2.0.tar.gz -C ../software/

# ./configure --prefix=/usr/local/nginx --add-module=../nginx_upload_module-2.2.0 --with-http_secure_link_module

# make

# make install

# vi nginx.conf

user www-data;

worker_processes 20;

error_log logs/error.log notice;

working_directory /usr/local/nginx;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application/octet-stream;

root /www/web/upload;

server {

listen 80;

server_name 192.168.41.129;

 

error_page 405 =200 @405; //處理405錯誤

location / {

index index.html index.htm index.php;

}

location @405

{

root /www/web/upload;

}

location ~ \.php$ {

try_files $uri /404.html;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include /etc/nginx/fastcgi_params;

}

client_max_body_size 100m;

# 上傳頁面提交到這個location

location /upload {

# 檔案上傳以後轉交給後端的php程式碼處理

upload_pass @test;

# 上傳檔案的臨時儲存位置,目錄是雜湊的,應該存在子目錄0 1 2 3 4 5 6 7 8 9

upload_store /www/web/upload/tmp 1;

upload_store_access user:r;

# 設定請求體的欄位

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;

# 指示後端關於上傳檔案的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 "^submit$|^description$";

upload_pass_args on;

}

# 將請求轉到後端的地址處理

location @test {

rewrite ^(.*)$ /test.php last;

}

}

}

  

四. 上傳介面

# cat /www/web/upload/upload.html

<html>

<head>

<title>Test upload</title>

</head>

<body>

<h2>Select files to upload</h2>

<form enctype="multipart/form-data" action="/upload" method="post">

<input type="file" name="file1"><br>

<input type="file" name="file2"><br>

<input type="file" name="file3"><br>

<input type="file" name="file4"><br>

<input type="file" name="file5"><br>

<input type="file" name="file6"><br>

<input type="submit" name="submit" value="Upload">

<input type="hidden" name="test" value="value">

</form>

</body>

</html>

  

五. upload_pass處理內容

# cat test.php //這裡只是簡單的打印出來,便於先理解上傳原理。請對著輸出內容理解下nginx upload module配置引數。

<?php

print_r($_POST);

?>

對上傳檔案的處理請參考:http://cn.php.net/manual/en/features.file-upload.php

六. 測試

http://192.168.41.129/upload.html

輸出內容如下所示:

Array

(

[file1_name] => Learning Perl, Sixth Edition.pdf

[file1_content_type] => application/pdf

[file1_path] => /www/web/upload/tmp/4/0000000014

[file1_md5] => 87032cc58109f5c6bb866d2684f9b48c

[file1_size] => 8927511

[file2_name] => Programming Perl, 4th Edition.pdf

[file2_content_type] => application/pdf

[file2_path] => /www/web/upload/tmp/5/0000000015

[file2_md5] => 82a52df177a8912c06af276581cfd5e4

[file2_size] => 21146356

[submit] => Upload

)

注意:需要修改php.ini以下引數

file_uploads on 是否允許通過http上傳

upload_max_filesize 8m 允許上傳檔案的最大大小

post_max_size 8m 通過表單POST給php所能接收的最大值

另外nginx.conf中設定上傳檔案大小

upload_max_file_size 軟限制

client_max_body_size 硬限制