nginx上傳模塊nginx_upload_module和nginx_uploadprogress_module模塊進度顯示,如何傳遞GET參數等。

ownload:
http://www.grid.net.ru/nginx/download/nginx_upload_module-2.2.0.tar.gz
configure and make :javascript

  1. ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module   --add-module=/data/software/lnmp1.1-full/nginx_http_push_module-0.73 --add-module=/data/software/lnmp1.1-full/ngx_cache_purge-2.1 --add-module=/data/software/lnmp1.1-full/nginx_upload_module-2.2.0  


Nginx配置文件:




較靠譜的文章:http://blog.sina.com.cn/s/blog_704836f401014bpj.html
<?php
$temppath = $_POST["file1_path"];
$name = $_POST["file1_name"];
$md5 = $_POST["file1_md5"];
$f_dir = substr($md5,0,1);
$s_dir = substr($md5,-1);
$final_file_path = "/".$f_dir."/".$s_dir."/".$name;

echo $temppath."<br />";
echo $name."<br />";
echo $md5."<br />";
echo $f_dir."<br />";
echo $s_dir."<br />";
echo $final_file_path;
rename($temppath,$final_file_path);
?>

由於nginx upload module已經作完了最費時的mime解析工做,後端的PHP代碼只須要簡單的移動文件到合適的位置就能夠了。由於upload module是使用C語言寫的,比起PHP做解析工做的效率高多了,所以極大地提升了文件上傳的效率。

2、upload module的配置參數簡要說明

下邊是一些配置參數的說明:

upload_pass 指明瞭須要後續處理的php地址
upload_cleanup 若是php出現400 404 499 500-505之類的錯誤,則刪除上傳的文件
upload_store 上傳文件存放地址
upload_store_access 上傳文件的訪問權限,user:r是指用戶可讀
upload_limit_rate 上傳限速,若是設置爲0則表示不限制
upload_pass_form_field 從表單原樣轉到後端的參數,能夠正則表達式表示
官方的例子是upload_pass_form_field "^submit$|^description$";
意思是把submit,description這兩個字段也原樣經過upload_pass傳遞到後端php處理。若是但願把全部的表單字段都傳給後端能夠用upload_pass_form_field "^.*$";


---------------

背景:追求極致,由服務器腳本(好比PHP)來負責接收上傳的數據。這種方式存在性能和效率的問題。因此,決定採用Nginx的上傳模塊來完成接收數據的功能,接收完數據後,再去轉給後端腳本語言進行後續處理(好比:移動文件、插入文件的信息到數據庫中)。

RFC 1867:
module for nginx web server for handling file uploads using multipart/form-data encoding (RFC 1867) and resumable uploads according to this protocol.
Description

The module parses request body storing all files being uploaded to a directory specified by upload_store directive. The files are then being stripped from body and altered request is then passed to a location specified by upload_pass directive, thus allowing arbitrary handling of uploaded files. Each of file fields are being replaced by a set of fields specified by upload_set_form_field directive. The content of each uploaded file then could be read from a file specified by $upload_tmp_path variable or the file could be simply moved to ultimate destination. Removal of output files is controlled by directive upload_cleanup. If a request has a method other than POST, the module returns error 405 (Method not allowed). Requests with such methods could be processed in alternative location via error_page directive.

Nginx.conf
======================================================================php

  1. user  www www;  
  2.   
  3. worker_processes 5;  
  4.   
  5. error_log  /data1/logs/nginx_error.log  crit;  
  6.   
  7. pid        /usr/local/webserver/nginx/nginx.pid;  
  8.   
  9. #Specifies the value for maximum file descriptors that can be opened by this process.  
  10. worker_rlimit_nofile 51200;  
  11.   
  12. events  
  13. {  
  14.   use epoll;  
  15.   worker_connections 51200;  
  16. }  
  17.   
  18. http  
  19. {  
  20.   include       mime.types;  
  21.   default_type  application/octet-stream;  
  22.   
  23.   #charset  gb2312;  
  24.   
  25.   server_names_hash_bucket_size 128;  
  26.   client_header_buffer_size 32k;  
  27.   large_client_header_buffers 4 32k;  
  28.   client_max_body_size 8m;  
  29.   
  30.   sendfile on;  
  31.   tcp_nopush     on;  
  32.   
  33.   keepalive_timeout 60;  
  34.   
  35.   tcp_nodelay on;  
  36.   
  37.   fastcgi_connect_timeout 300;  
  38.   fastcgi_send_timeout 300;  
  39.   fastcgi_read_timeout 300;  
  40.   fastcgi_buffer_size 64k;  
  41.   fastcgi_buffers 4 64k;  
  42.   fastcgi_busy_buffers_size 128k;  
  43.   fastcgi_temp_file_write_size 128k;  
  44.   
  45.   gzip on;  
  46.   gzip_min_length  1k;  
  47.   gzip_buffers     4 16k;  
  48.   gzip_http_version 1.0;  
  49.   gzip_comp_level 2;  
  50.   gzip_types       text/plain application/x-javascript text/css application/xml;  
  51.   gzip_vary on;  
  52.   
  53.     server  
  54.     {  
  55.         listen 80;  
  56.         server_name test.local;  
  57.         index index.php index.shtml index.htm index.html;  
  58.         root  /data/app/test.local/wwwroot;  
  59.         access_log  off;  
  60.   
  61.         location /upload {  
  62.             upload_pass     /index.php?c=uploader&a=upload_server;  
  63.             upload_cleanup 400 404 499 500-505;  
  64.             upload_store    /data/app/test.local/upload_tmp;  
  65.             upload_store_access user:r;  
  66.             upload_limit_rate 128k;  
  67.             upload_set_form_field "${upload_field_name}_name" $upload_file_name;  
  68.             upload_set_form_field "${upload_field_name}_content_type" $upload_content_type;  
  69.             upload_set_form_field "${upload_field_name}_path" $upload_tmp_path;  
  70.             upload_aggregate_form_field "${upload_field_name}_md5" $upload_file_md5;  
  71.             upload_aggregate_form_field "${upload_field_name}_size" $upload_file_size;  
  72.             upload_pass_form_field "^.*$";  
  73.         }  
  74.   
  75.         location ~ .*\.php?$  
  76.         {  
  77.             #include fastcgi_params;  
  78.             fastcgi_pass  127.0.0.1:9000;   
  79.             fastcgi_index index.php;        
  80.             include fcgi.conf;              
  81.         }  
  82.   
  83.         location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {  
  84.             expires      30d;  
  85.         }  
  86.   
  87.         location ~ .*\.(js|css)?$ {  
  88.             expires      1d;  
  89.         }  
  90.   
  91.   
  92.     }  
  93. }  


1.上面的#include fastcgi_params; 被我註釋掉了,不然出現:405 Method not allowed ,查了下:
Nginx 靜態文件中的 POST 請求返還 405 Method not allowed 錯誤,因而用了9000的PHP端口。
index.php 內容:css

  1. <?php                     
  2. print_r($_POST);          
  3. echo $upload_tmp_path;    
  4. $temppath = $_POST["file1_path"];  
  5. $name = $_POST["file1_name"];  
  6. $md5 = $_POST["file1_md5"];  
  7. $f_dir = substr($md5,0,1);  
  8. $s_dir = substr($md5,-1);  
  9. $final_file_path = "/".$f_dir."/".$s_dir."/".$name;  
  10.   
  11. echo $temppath."<br />";  
  12. echo $name."<br />";  
  13. echo $md5."<br />";  
  14. echo $f_dir."<br />";  
  15. echo $s_dir."<br />";  
  16. echo $final_file_path;  
  17. rename($temppath,$final_file_path);  
  18. ?>                          



上傳後返回:
Array
(
    [file1_name] => 6597350142123536341.jpg
    [file1_content_type] => image/jpeg
    [file1_path] => /data/app/test.local/upload_tmp/0000000001
    [file1_md5] => 5a84d879e497bf64acebdc84c4701a76
    [file1_size] => 110001
    [file2] => 
    [file3] => 
    [file4] => 
    [file5] => 
    [file6] => 
    [submit] => Upload
    [test] => value
)
先看一下這個上傳目錄的結構是這樣的,這些編號的都是上傳的素材,沒有後綴:
/data/app/test.local/upload_tmp# ls
0000000001  0006630963  0006630964

查看目錄下有沒有這個文件:
ls /data/app/test.local/upload_tmp/0000000001
/data/app/test.local/upload_tmp/0000000001
sz 下來,改名爲.jpg的:
sz  /data/app/test.local/upload_tmp/0000000001 ==》0000000001.jpg ,打開一看果真是我上傳的文件,得證!

把這個文件放到本身定義的目錄下:html

  1. <?php                                   
  2. $temppath = $_POST["file1_path"];       
  3. $name = $_POST["file1_name"];           
  4. $orgFileName = "/data1/files/".$name;   
  5. rename($temppath,$orgFileName);         
  6. ?>                                      


多個文件的一個狀況,也就是多個文件的POST數組規律,去進行移動文件便可:
<input type="file" name="file2">
<input type="file" name="file2">
  
[file1_name] => 1332460275090024.jpg
[file1_content_type] => image/jpeg
[file1_path] => /data/app/test.local/upload_tmp/0000000034
[file1_md5] => 4e84aac3bc2cc25b7c69c7b506e4967f
[file1_size] => 73702
[file2_name] => desktop.ini
[file2_content_type] => application/octet-stream
[file2_path] => /data/app/test.local/upload_tmp/0000000035
[file2_md5] => dc723b859dec1526568ad581aec334d5

由於nginx upload module已經作完了最費時的mime解析工做,後端的PHP代碼只須要簡單的移動文件到合適的位置就能夠了。由於upload module是使用C語言寫的,比起PHP做解析工做的效率高多了,所以極大地提升了文件上傳的效率。

upload_cleanup 若是php出現400 404 499 500-505之類的錯誤,則刪除上傳的文件,這塊能夠利用PHP進行邏輯判斷後輸出header頭來進行操做是否刪除文件。
======================================================================
補安裝編譯方法:
1.下載
wget http://www.grid.net.ru/nginx/download/nginx_upload_module-2.2.0.tar.gz
2.編譯(在NGINX編譯目錄執行如下命令, 其中 --add-module=你下載解壓的上傳插件目錄)
./configure --user=www --group=www --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module   --add-module=/root/software/nginx_http_push_module-0.692   --add-module=/root/software/ngx_cache_purge-1.3 --add-module=/root/software/nginx_upload_module-2.2.0

3.上傳界面:


參考來源:
1)nginx上傳模塊—nginx upload module安裝:http://waynerqiu.com/7/136.html
2)寫得很簡潔的安裝方法:http://foooy.me/nginx/158.html  【該文裏提到的接受PHP,這塊沒有作詳細的配置,參考上面這篇文章便可。】
3)http://anerg.com/read.php?55  
//這一篇文章描述到:upload_pass     /index.php?c=uploader&a=upload_server; 也就是有框架時怎麼用框架的action來進行處理。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------
最後,後記備查用相關模塊的使用:
據說有一個哥們解決了get的問題,經過相關nginx的指令實現的,沒實踐:http://waynerqiu.com/7/139.html
還有實現斷點續傳,進度顯示等的:
最近作一個產品,須要實現從網頁上傳文件給服務器。通常狀況下都是採用Ajax異步方式,建立一個iframe,在iframe裏面把數據以form方式提交給後端的服務器腳本,由服務器腳本(好比PHP)來負責接收上傳的數據。這種方式存在性能和效率的問題。因此,決定採用Nginx的上傳模塊來完成接收數據的功能,接收完數據後,再去轉給後端腳本語言進行後續處理(好比:移動文件、插入文件的信息到數據庫中)。同時,因爲須要在前端展示上傳的進度,所以能夠利用Nginx一個uploadprogress模塊來獲取。
     整個處理框圖以下:
     點擊在新窗口中瀏覽此圖片

實現步驟:
     一、查看Nginx是否安裝了這兩個模塊(nginx_upload_module和nginx_uploadprogress_module),命令nginx -V (注意是大寫),能夠查看Nginx當時編譯時候的參數,若是發現有上述兩個模塊,說明Nginx已經安裝了這兩個模塊。若是沒有的話,就須要安裝這兩個Nginx模塊。因爲這兩個模塊不在Nginx源代碼中,須要從新編譯Nginx,在編譯選項中加上
    --add-module=/模塊源代碼路徑/nginx_upload_module-2.2.0 --add-module=/模塊源代碼路徑/nginx_uploadprogress_module-0.8.2 。
      二、因爲產品的前端使用的是jQuery框架,因此,找了一個現成的jQuery下的上傳文件插件(ajaxfileupload)。該代碼基本原理就是動態建立一個iframe,在iframe中再增長一個form,最後數據放到這個form中提交給服務器,代碼量比較小也就200來行代碼。前端的代碼以下:前端

  1. <script type="text/javascript" src="http://192.168.1.203:7100/js/libs/ajaxfileupload.js" ></script>  
  2. <script type="text/javascript">  
  3.     function uploadfile(){          
  4.         $.ajaxFileUpload({  
  5.             url:'http://192.168.1.203:7100/upload/‘,//上傳的地址 
  6.             sercureuri:false, 
  7.             fileElementId:'fileToUpload', 
  8.             dataType:'json', 
  9.             success:function(data,status){ 
  10.                 if(typeof(data.error) != 'undefined'){ 
  11.                     if(data.error != '')  
  12.                         alert(data.error);  
  13.                 }  
  14.                 else{  
  15.                     alert(data.msg);  
  16.                 }  
  17.             },  
  18.             error:function(data,status, e){  
  19.                 alert(e);  
  20.             }  
  21.         });  
  22.         return false;  
  23.     }     
  24. </script>  
  25. <div>  
  26. <input type="file" name="addfile" size="50" id="fileToUpload" />  
  27. <input type="button" value="上傳" onclick="return uploadfile();"/>  
  28. </div>  



其中,success的回調函數參數是服務器返給瀏覽器的結果。
三、配置Nginx,實現上傳模塊來接收頁面上傳的文件。把下面配置添加到Nginx的配置文件中,注意是加在server的上下文中。
        location = /upload {
                upload_pass     /service.php?path=uploadfile&a=upload_server;//表示Nginx接收完上傳的文件後,而後交給後端處理的地址
                upload_cleanup 400 404 499 500-505; //表示當發生這些http status代碼的狀況下,會把上傳的文件刪除
                upload_store    /tmp/upload_tmp 1;//上傳模塊接收到的文件臨時存放的路徑, 1 表示方式,該方式是須要在/tmp/upload_tmp下建立以0到9爲目錄名稱的目錄,上傳時候會進行一個散列處理。
                upload_store_access user:r; //指定訪問模式
                upload_limit_rate 128k; //設定上傳速度上限
                upload_set_form_field "${upload_field_name}_name" $upload_file_name; //設定後續腳本語言訪問的變量,其中${upload_field_name}對照本例子就是addfile。好比後臺PHP就能夠經過$_POST['addfile_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_store設置了臨時文件存放根路徑,該路徑就是通過散裂後上傳文件存在真實路徑,好比後續處理能夠根據這值把上傳文件拷貝或者移動到指定的目錄下。
                upload_pass_form_field "^.*$";//
                upload_pass_args on;// 打開開關,意思就是把前端腳本請求的參數會傳給後端的腳本語言,好比:http://192.168.1.203:7100/upload/?k=23.PHP腳本能夠經過$_POST['k']來訪問。
        }
四、上述配置完了,就能夠實現上傳的功能了。可是,要獲取上傳的進度,那仍是須要配置另一個模塊nginx_uploadprogress_module。其實,獲取當前進度原理比較簡單,就是經過javascript以異步方式定時給特定地址發送請求,這個模塊會以json格式返回上傳的進度。配置比較簡單。
          1)、首先打開這個模塊功能,在Nginx配置文件中http上下文裏面,增長upload_progress proxied 5m;其中,proxied表示名稱(zone_name官方文檔),5m表示每次連接存放跟蹤信息的大小。另外,再設置返回格式爲json,upload_progress_json_output;
          2)、在上述的location = /upload中增長一個配置項track_uploads proxied 30s; 其中,proxied就是剛纔在第一步設置的名字,30s表示每次連接處理完畢後,連接會保持30s。
          3)、設置一個location來處理javascript發送請求。
          location ^~ /progress {

  report_uploads proxied;    #GET此地址獲得上傳進度
}
           4)、還有一個參數考慮設置upload_progress_header ,這個值缺省是X-Progress-ID。有點相似SessionID,主要用在前臺須要在上傳文件的時候須要設置這個參數值,好比設置爲uuid值。這樣javascript每次發送請求要獲取上傳進度時候,都須要帶上這個參數,這樣上傳進度跟蹤模塊才知道是返回那個連接的進度。
           通過這三步驟,就把上傳進度跟蹤模塊配置好了。如今就須要對前臺腳本就行修改
五、修改第2步的前臺腳本

java

  1. <script type="text/javascript" src="http://192.168.1.203:7100/js/libs/ajaxfileupload.js" ></script>  
  2. <script type="text/javascript">  
  3.     <strong>var interval = undefined;</strong>  
  4.     function uploadfile(){    
  5.         var uuid = "";  
  6.         for (var i = 0; i < 32; i++) {  
  7.             uuid += Math.floor(Math.random() *16).toString(16);  
  8.         }        
  9.         $.ajaxFileUpload({  
  10.             url:'http://192.168.1.203:7100/upload/<strong>?X-Progress-ID=' + uuid</strong>,//上傳的地址  
  11.             sercureuri:false,  
  12.             fileElementId:'fileToUpload',  
  13.             dataType:'json',  
  14.             success:function(data,status){  
  15.                 if(typeof(data.error) != 'undefined'){  
  16.                     if(data.error != '')  
  17.                         alert(data.error);  
  18.                 }  
  19.                 else{  
  20.                     alert(data.msg);  
  21.                 }  
  22.             },  
  23.             error:function(data,status, e){  
  24.                 alert(e);  
  25.             }  
  26.         });  
  27.       <strong>  interval = window.setInterval(  
  28.            function () {  
  29.              getUploadProgress(uuid);  
  30.            },  
  31.            2000  
  32.          );</strong>  
  33.         return false;  
  34.     }     
  35.  <strong>   function getUploadProgress(uuid){  
  36.       etajax.sendRequest('http://192.168.1.203:7100/progress/',"GET","X-Progress-ID=" + uuid,getUploadProgressCallback);  
  37.     }  
  38.     function getUploadProgressCallback(type, json, http){  
  39.         if(type == "load"){  
  40.             var bar = document.getElementById('tp');  
  41.             if(json.state == "uploading"){  
  42.                    
  43.                  var w =  Math.floor(json.received * 100.0 / json.size) ;  
  44.                  bar.innerHTML = w + "%";  
  45.             }  
  46.                 /* we are done, stop the interval */  
  47.              if (json.state == 'done') {  
  48.                 bar.innerHTML = "100%";  
  49.                  window.clearTimeout(interval);  
  50.             }  
  51.         }  
  52.     }     </strong>  
  53. </script>  
  54. <div>  
  55. <input type="file" name="addfile" size="50" id="fileToUpload" />  
  56. <input type="button" value="上傳" onclick="return uploadfile();"/>  
  57. </div>  
  58. <strong><div>  
  59.     <div id="tp">0%</div>  
  60. </div></strong>  



上述黑體就是增長的代碼,其中,有些函數是調用產品封裝好的函數,因此,不要所有照搬。主要是抓住如下幾個要點就能夠了:
    一、在上傳文件時候須要增長一個uuid,對應的參數就是upload_progress_header設置的,缺省是X-Progress-ID。
    二、在請求獲取進度的時候,都要帶上這個uuid。
    三、設定一個定時期,定時發送異步的GET方式請求,獲取進度數據。
    四、返回的json格式是{"state":"uploading", "size":3232,"received":34},其中上傳完畢state值爲done,若是發生錯誤會,state就是error,而且會返回status,錯誤編碼。
    
    步驟就介紹在這裏了。另外,javascript方式上傳文件,在用戶上傳文件時候,最好能獲取上傳文件大小,這樣能夠提早告訴用戶是否超出容許上傳的大小值。可是,目前javascript方式獲取文件大小要兼容全部瀏覽器仍是存在問題。我打算仍是寫個flash,經過flash方式來獲取,比較保險。

來自:http://blog.csdn.net/waden/article/details/7040123

更多參考:http://blog.sina.com.cn/s/blog_704836f401014bpj.htmlnode

做者:justwinit@向東博客 專一WEB應用 構架之美 --- 構架之美,在於盡態極妍 | 應用之美,在於藥到病除
地址:http://justwinit.cn/post/6221/
版權全部。轉載時必須以連接形式註明做者和原始出處及本聲明!
nginx

相關文章
相關標籤/搜索