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

  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作解析工作的效率高多了,因此极大地提高了文件上传的效率。

二、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
======================================================================

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

1.上面的#include fastcgi_params; 被我注释掉了,否则出现:405 Method not allowed ,查了下:
Nginx 静态文件中的 POST 请求返还 405 Method not allowed 错误,于是用了9000的PHP端口。
index.php 内容:

  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. echo $temppath."<br />";
  11. echo $name."<br />";
  12. echo $md5."<br />";
  13. echo $f_dir."<br />";
  14. echo $s_dir."<br />";
  15. echo $final_file_path;
  16. rename($temppath,$final_file_path);
  17. ?>

上传后返回:
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 ,打开一看果然是我上传的文件,得证!

把这个文件放到自己定义的目录下:

  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模块来获取。
     整个处理框图如下:
     

实现步骤:
     1、查看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 。
      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的回调函数参数是服务器返给浏览器的结果。
3、配置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']来访问。
        }
4、上述配置完了,就可以实现上传的功能了。但是,要获取上传的进度,那还是需要配置另外一个模块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每次发送请求要获取上传进度时候,都需要带上这个参数,这样上传进度跟踪模块才知道是返回那个链接的进度。
           经过这三步骤,就把上传进度跟踪模块配置好了。现在就需要对前台脚本就行修改
5、修改第2步的前台脚本

  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. var w =  Math.floor(json.received * 100.0 / json.size) ;
  43. bar.innerHTML = w + "%";
  44. }
  45. /* we are done, stop the interval */
  46. if (json.state == 'done') {
  47. bar.innerHTML = "100%";
  48. window.clearTimeout(interval);
  49. }
  50. }
  51. }     </strong>
  52. </script>
  53. <div>
  54. <input type="file" name="addfile" size="50" id="fileToUpload" />
  55. <input type="button" value="上传" onclick="return uploadfile();"/>
  56. </div>
  57. <strong><div>
  58. <div id="tp">0%</div>
  59. </div></strong>

上述黑体就是增加的代码,其中,有些函数是调用产品封装好的函数,所以,不要全部照搬。主要是抓住以下几个要点就可以了:
    1、在上传文件时候需要增加一个uuid,对应的参数就是upload_progress_header设置的,缺省是X-Progress-ID。
    2、在请求获取进度的时候,都要带上这个uuid。
    3、设定一个定时期,定时发送异步的GET方式请求,获取进度数据。
    4、返回的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.html

作者:justwinit@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:http://justwinit.cn/post/6221/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!

nginx上传模块nginx_upload_module和nginx_uploadprogress_module模块进度显示,如何传递GET参数等。的更多相关文章

  1. 解决nginx上传模块nginx_upload_module传递GET参数

    解决nginx上传模块nginx_upload_module传递GET参数的方法总结 最近用户反映我们的系统只能上传50M大小的文件, 希望能够支持上传更大的文件. 很显然PHP无法轻易实现大文件上传 ...

  2. nginx上传文件时 nginx 413 Request Entity Too Large 错误

    产生原因: 上传文件的大小超出了 Nginx 允许的最大值,默认是1M: 解决方法: 修改Nginx的配置文件(一般是:nginx/nginx.conf),在 http{} 段中增大nginx上传文件 ...

  3. FTP文件上传 支持断点续传 并 打印下载进度(二) —— 单线程实现

    这个就看代码,哈哈哈哈哈  需要用到的jar包是: <dependency> <groupId>commons-net</groupId> <artifact ...

  4. iOS10 开发权限适配设置 崩溃(上传打包后构建版本一直不显示)

    ios10 系统必须强制配置系统权限 如果不配置,调试的时候导致崩溃,还会引发包无效的问题,导致上传打包后构建版本一直不显示 解决方案1.在项目中找到info.plist文件,右键点击以 Source ...

  5. nginx上传模块nginx_upload_module使用

    1.安装模块 1 cd /data/software 2 wget http://www.grid.net.ru/nginx/download/nginx_upload_module-2.0.12.t ...

  6. nginx上传模块—nginx upload module-

    一. nginx upload module原理 官方文档: http://www.grid.net.ru/nginx/upload.en.html Nginx upload module通过ngin ...

  7. asp.net上传大文件-请求筛选模块被配置为拒绝超过请求内容长度的请求

    HTTP错误404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求,原因是Web服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值(IIS 7 默认文件上传大 ...

  8. Nginx上传文件返回413的解决

    通过http上传文件时返回403 Request Entity Too Large错误时,原因是默认设置的允许上传文件太小,默认是2M,如果上传文件大小大于2M时,那么就会返回413的错误,修改ngi ...

  9. Nginx上传文件失败

    公司用Nginx做反向代理,出现了上传文件失败的问题,通过查看错误日志,发现是上传文件太大的缘故. 通过查找资料,才知道nginx默认最大上传文件时1M.这就需要修改配置文件,将上传文件大小进行修改. ...

随机推荐

  1. python Post方式发起http请求 使用百度接口地理编码

    import os import httplib import json import urllib baiduapi="api.map.baidu.com:80" src=&qu ...

  2. c# Parallel并行运算

    string str = ""; DataTable dt=new DataTable(); dt.Columns.Add("name", typeof(Sys ...

  3. 不同服务器数据库之间的数据操作 sp_addlinkedserver

    --创建链接服务器  exec sp_addlinkedserver   'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '  exec sp_addlinkedsrv ...

  4. position属性absolute与relative(转)

    每次要用到Position属性时,总要去搜索下,这两个属性值的区别:今天就直接复制网上的结果,以便以后多看看. Absolute,CSS中的写法是:position:absolute; 他的意思是绝对 ...

  5. 自己动手写PHP MVC框架

    自己动手写PHP MVC框架 来自:yuansir-web.com / yuansir@live.cn 代码下载: https://github.com/yuansir/tiny-php-framew ...

  6. 序列化类型为“System.Reflection.Module”的对象时检测到循环引用

    在使用ajax调用web services时,正好返回的类型为datatable,想用通过json方式直接解析,但调用后,得到如下错误: 序列化类型为“System.Reflection.Module ...

  7. Qt中实现启动画面(延时过程中要加上app.processEvents())

    纵所周之,当一个程序的启动比较耗时的时候,为了不让用户枯燥的等待或者是误以为程序运行异常了,所以我们都会在启动比较耗时的程序中加上启动界面 ,例如office软件等等. 在Qt中实现启动界面,主要就是 ...

  8. Android 圆形按钮实现

    项目中用到的圆形按钮,做个半天,用sharp形式实现,样式代码如下: <Button android:id="@+id/btn_5" android:layout_width ...

  9. jdk8预览

    原文:http://www.techempower.com/blog/2013/03/26/everything-about-java-8/ 1.接口增强 (1)接口可以定义static方法 java ...

  10. zhihu spark集群,书籍,论文

    spark集群中的节点可以只处理自身独立数据库里的数据,然后汇总吗? 修改 我将spark搭建在两台机器上,其中一台既是master又是slave,另一台是slave,两台机器上均装有独立的mongo ...