Nginx初步-3:使用nginx-upload-module显示上传进度

准备工作

现在nginx-upload-module模块已经加入到Nginx,但还不能直接使用,还有一些准备工作要做。


准备JavaScript脚本

首先,下载或直接链接jQuery.js,因为模块要配合使用jQuery来控制HTML元素显示进度。

<head>
...
<script type="text/javascript" src="/js/jquery.js"></script>

...
</head>

<head>
...

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

...
</head>

关键是还需要另一个脚本:jquery.uploadProgress.js。可以从 这里下载。

别忘了在你的页面中包含该脚本。

同样滴,由于jQuery已经变化,不再支持$.browser.safari,所以我们需要修改jquery.uploadProgress.js。

将所有这样的代码:

$.browser.safari
修改成:

navigator.userAgent.match(/safari/i)
该修正参考自 这里,原意是针对IE的,可以依样画葫芦。

原文这么说:

...

as far of jquery 1.9 jQuery.browser was removed, adn admin_menu get this error:
"Uncaught TypeError: Cannot read property 'msie' of undefined" (admin_menu.js - line:223)

For quick fix use this code:
change line 223:
- if ($.browser.msie && parseInt(jQuery.browser.version) == 6) {
+ if (navigator.userAgent.match(/msie [6]/i)) {

...

修改Nginx配置文件

首先要修改/etc/nginx.conf文件,加大允许上传的文件尺寸,并配置上传进度报告的尺寸间隔,这里设置为50k一报告。

http {

	##
	# Basic Settings
	##
	
	...

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;
	
	# REV:igame@Dec-22-2013: Change size from 2m to 256m.
	client_max_body_size 256M;
	
	# REV:igame@Dec-22-2013: Followed the instruction of http://wiki.nginx.org/HttpUploadProgressModule
	upload_progress proxied 50k;

        ...

再修改/etc/nginx/sites-available/default文件中的location ~ \.php$小节,根据指南,track_uploads必须是最后一行。

location ~ \.php$ {
		...
	# track uploads in the 'proxied' zone
        # remember connections for 30s after they finished
        track_uploads proxied 30s;
}

并添加下面的内容:

location ^~ /progress {
	upload_progress_json_output;
	report_uploads proxied;
}

使用upload_progress_json_output是因为jQuery会按json模式解析数据,不加这一行将导致解析失败,也就不能显示进度了。

修改PHP配置

打开/etc/php5/fpm/php.ini文件,修改以下内容:

...
; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On

...
;post_max_size = 8M
post_max_size = 256M

...

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
;upload_max_filesize = 2M
upload_max_filesize = 256M

...

允许文件上传,并允许上传最大256M的文件。如果文件太小了,一忽儿就完毕了,也就无法看到进度了。


编写页面

现在编写上传页面,假设叫learn.php,内容如下:

<html>
<head>
	<script type="text/javascript" src="/js/jquery.js"></script>
	<script type="text/javascript" src="/js/jquery.uploadProgress.js"></script>
	<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> -->
	
	<style>
		.bar {
		  width: 300px;
		}
		  
		#progress {
		  background: #eee;
		  border: 1px solid #222;
		  margin-top: 20px;
		}

		#progressbar {
		  width: 0px;
		  height: 24px;
		  background: #333;
		}
	
	</style>
</head>
<body>

<form id="form1" action="ulfile.php" method="POST" enctype="multipart/form-data">
Filename: <input type="file" name="file1" />
<input type="submit" value="Upload" />
</form>

<div id="uploading">
  <div id="progress" class="bar">
    <div id="progressbar"> </div>
    <div id="percents"></div>
  </div>
</div>

<script type="text/javascript">
$(function() {
	  $('form').uploadProgress({
		/* scripts locations for safari */
		jqueryPath: "/js/jquery.js",
		uploadProgressPath: "/js/jquery.uploadProgress.js",
		start: function() {
			// Add start code here.
		},
		/* function called each time bar is updated */
		uploading: function(upload) {
			$('#percents').html(upload.percents+'%');
		},
		
		/* selector or element that will be updated */
		progressBar: "#progressbar",

		/* progress reports url */
		progressUrl: "/progress",

		/* how often will bar be updated */
		interval: 500
	  });
	});
</script>
</body>
</html>

注意,该页面可能不能在你的机器上运行,因为脚本路径与你的实际情况不一致。

再编写上传完成后的页面,假设名字叫ulfile.php,内容如下:


<?php
        if ($_FILES["file1"])
	{
                echo "Congratulations!<br />";

		if ($_FILES["file1"]["error"] > 0)
		{
			echo "Error:" . $_FILES["file1"]["error"] . "<br />";
		}
		else
		{
		
			echo "Source File: " . $_FILES["file1"]["name"] . "<br>";
			echo "Type: " . $_FILES["file1"]["type"] . "<br>";
			echo "Size: " . round($_FILES["file1"]["size"] / 1024) . " kB<br>";
			echo "Stored in: " . $_FILES["file1"]["tmp_name"];
			echo "<br />";
		
			$uploaddir = './upload/'; // /usr/share/nginx/www/upload/';
                        // 注意,英文文件名不需要解码,但中文需要。
			// $uploadfile = $uploaddir . basename($_FILES['file1']['tmp_name']);
			$uploadfile = $uploaddir . html_entity_decode(basename($_FILES['file1']['name']));
			
			echo "Destination:" . $uploadfile . "<br />";
		
			if (move_uploaded_file($_FILES['file1']['tmp_name'], $uploadfile))
			{
				echo "File successfully uploaded.<br />";
				/* 如果不想保存,只是测试进度条,可以在上传完成后立即删除。
				if (!unlink($uploadfile))
					echo "Can't delete the uploaded file.<br />";
				*/
			}
			else
				echo "Failed to save file.<br />";
		}
	}

注意,如果遇到目录问题,比如这里使用upload目录,而你没有,你需要建立这样的目录并设置相当权限(root)。

好了,现在可以心情的享受你的上传进度条了,小心不要爆了你的硬盘。


问题

问题主要集中在路径上,比如js的路径,目录的权限,致命的413错误等。


你可能感兴趣的:(jquery,nginx,PHP,php-fpm)