[转]一个文件上传的jquery插件
http://www.jb51.net/article/51547.htm
无论是PHP,还是其他的服务端脚本都提供了文件上传功能,实现起来也比较简单。而利用JavaScript来配合,即可实现Ajax方式的文件上传。虽然jQuery本身没有提供这样的简化函数,但有不少插件可以实现。其中,Phpletter.com提供的ajaxfileupload.js是一个轻量的插件,而且编写方式与jQuery提供的全局方法$.post()非常相似,简单易用。 不过,该插件实在太简化了,除了可提供需上传文件的路径外,也就不能传递额外的值到后台服务端。所以,我修改了一下该脚本,增加个一个data对象参数。
一、原理
我这里使用的是PHP作为服务端脚本,几乎在每本较少PHP的书上都会提到如何使用move_uploaded_file()方法来上传文件,这里我就不再细说了。我想说的是,利用Ajax上传的原理。 因为一直在使用jQuery库,所以当想到Ajax时,第一反应就是试试$.post()方法,利用各选择器得到file文件框中的value值,然后提交到后台服务端。当然,后来证明这是不行的。(正因为这问题,我还查了不少资料,网上还提供了不少ASP等方式的脚本,真不知道该说什么好。。) 回到正题,要实现Ajax方式上传,其实并不难,方法也有不少。而本文提到的Phpletter.com的ajaxfileupload.js插件就是使用iframe的方式。这也是在不使用JavaScript脚本时,要实现不刷新页面上传时常见的方法。(本博客bo-blog后台撰写日志就是用该方法) 而ajaxfileupload.js插件也很简单,就是先利用jQuery的选择器获得file文件上传框中的文件路径值,然后动态的创建一个iframe,并在里面建立一个新的file 文件框,提供post方式提交到后台。最后,返回结果到前台。
二、使用
ajaxfileupload.js插件的使用很简单。 前台HTML代码类似:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<script type= "text/javascript" > $( #buttonUplod).click(function () { $.ajaxFileUpload ({ url: 'doajaxfileupload.php' , //你处理上传文件的服务端 secureuri: false , //与页面处理代码中file相对应的ID值 fileElementId: 'img' , dataType: 'json' , //返回数据类型:text,xml,json,html,scritp,jsonp五种 success: function (data) { alert(data.file_infor); } }) }); </script> <input id= "img" type= "file" size= "45" name= "img" > <button id= "buttonUpload" onclick= "return ajaxFileUpload();" >Upload</button> |
后台doajaxfileupload.php脚本:
1
2
3
4
5
6
7
8
9
|
<?php $upFilePath = "../attachment/" ; $ok =@move_uploaded_file( $_FILES [ 'img' ][ 'tmp_name' ], $upFilePath ); if ( $ok === FALSE){ echo json_encode( 'file_infor' => '上传失败' ); } else { echo json_encode( 'file_infor' => '上传成功' ); } ?> |
为了测试,可以使用类似下面的方式保存传递过来的变量值:
$file_info = var_export($_FILES,true); $ok = file_put_contents("../attachment/file_info.txt",$file_info); if ($ok) exit(json_encode('file_infor'=>'上传成功')); exit (json_encode('file_infor'=>'上传失败'));
※ 注意 请留意HTML代码文件框中的标记:
1. id='img'是用于给ajaxfileupload.js插件的fileElementId:'img'识别的,jQuery选择器会利用该字符串获得文本框的值; 2. name='img'是用于通过post方式提交到后台脚本时,PHP通过$_FILES['img']读取上传文件的数据,若没有该值,$_FILES变量为空;
所以,这两个值缺一不可,也不可混淆。
三、支持额外参数
有时候,我们需要在后台根据某些变量来觉得对上传文件的处理。例如,更新文件。这时,就需要往同台再传递一些额外的参数。所以,我修改了ajaxfileupload.js插件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
addOtherRequestsToForm: function (form,data) { // add extra parameter var originalElement = $( '<input type="hidden" name="" value="">' ); for ( var key in data) { name = key; value = data[key]; var cloneElement = originalElement.clone(); cloneElement.attr({ 'name' :name, 'value' :value}); $(cloneElement).appendTo(form); } return form; }, ajaxFileUpload: function (s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime() var form = jQuery.createUploadForm(id, s.fileElementId); if ( s.data ) form = jQuery.addOtherRequestsToForm(form,s.data); var io = jQuery.createUploadIframe(id, s.secureuri); |
红色标记部分是我添加的内容。这样,我就可以在前台HTML部分,通过类似下面的代码来传递额外的参数:
url:'doajaxfileupload.php', //你处理上传文件的服务端 secureuri:false, //与页面处理代码中file相对应的ID值 data:{'test':'test','ok':'ok'}, //以对象的方式传递,内容部分可输入JavaScript的变量值 fileElementId:'img',
后台处理脚本为:
1
2
3
4
5
|
array_push ( $_FILES , $_REQUEST ); $file_info = var_export( $_FILES ,true); $ok = file_put_contents ( "../attachment/file_info.txt" , $file_info ); if ( $ok ) exit (json_encode( 'file_infor' => '上传成功' )); exit (json_encode( 'file_infor' => '上传失败' )); |
可见,原理很简单,就是把额外的data对象内容一同加到iframe下的form中,传递到后台PHP脚本,以$_REQUEST等变量获得这些值。 后台输出保留的file_info.txt内容如下:
array ( 'file' => array ( 'name' => 'firefox-java.txt', 'type' => 'text/plain', 'tmp_name' => 'D:\\Tools\\xampp\\tmp\\phpED45.tmp', 'error' => 0, 'size' => 250, ), 0 => array ( 'test' => 'test', 'ok' => 'ok', 'PHPSESSID' => 'e379fd4fb2abca6e802a1302805a5535', ), )
ajaxfileupload.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
jQuery.extend({ createUploadIframe: function (id, uri) { //create frame var frameId = 'jUploadFrame' + id; if (window.ActiveXObject) { var io = document.createElement( '<iframe id="' + frameId + '" name="' + frameId + '" />' ); if ( typeof uri== 'boolean' ){ io.src = 'javascript:false' ; } else if ( typeof uri== 'string' ){ io.src = uri; } } else { var io = document.createElement( 'iframe' ); io.id = frameId; io.name = frameId; } io.style.position = 'absolute' ; io.style.top = '-1000px' ; io.style.left = '-1000px' ; document.body.appendChild(io); return io }, createUploadForm: function (id, fileElementId) { //create form var formId = 'jUploadForm' + id; var fileId = 'jUploadFile' + id; var form = $( '<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>' ); var oldElement = $( '#' + fileElementId); var newElement = $(oldElement).clone(); $(oldElement).attr( 'id' , fileId); $(oldElement).before(newElement); $(oldElement).appendTo(form); //set attributes $(form).css( 'position' , 'absolute' ); $(form).css( 'top' , '-1200px' ); $(form).css( 'left' , '-1200px' ); $(form).appendTo( 'body' ); return form; }, addOtherRequestsToForm: function (form,data) { // add extra parameter var originalElement = $( '<input type="hidden" name="" value="">' ); for ( var key in data) { name = key; value = data[key]; var cloneElement = originalElement.clone(); cloneElement.attr({ 'name' :name, 'value' :value}); $(cloneElement).appendTo(form); } return form; }, ajaxFileUpload: function (s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime() var form = jQuery.createUploadForm(id, s.fileElementId); if ( s.data ) form = jQuery.addOtherRequestsToForm(form,s.data); var io = jQuery.createUploadIframe(id, s.secureuri); var frameId = 'jUploadFrame' + id; var formId = 'jUploadForm' + id; // Watch for a new set of requests if ( s.global && ! jQuery.active++ ) { jQuery.event.trigger( "ajaxStart" ); } var requestDone = false ; // Create the request object var xml = {} if ( s.global ) jQuery.event.trigger( "ajaxSend" , [xml, s]); // Wait for a response to come back var uploadCallback = function (isTimeout) { var io = document.getElementById(frameId); try { if (io.contentWindow) { xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML: null ; xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document; } else if (io.contentDocument) { xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML: null ; xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document; } } catch (e) { jQuery.handleError(s, xml, null , e); } if ( xml || isTimeout == "timeout" ) { requestDone = true ; var status; try { status = isTimeout != "timeout" ? "success" : "error" ; // Make sure that the request was successful or notmodified if ( status != "error" ) { // process the data (runs the xml through httpData regardless of callback) var data = jQuery.uploadHttpData( xml, s.dataType ); // If a local callback was specified, fire it and pass it the data if ( s.success ) s.success( data, status ); // Fire the global callback if ( s.global ) jQuery.event.trigger( "ajaxSuccess" , [xml, s] ); } else jQuery.handleError(s, xml, status); } catch (e) { status = "error" ; jQuery.handleError(s, xml, status, e); } // The request was completed if ( s.global ) jQuery.event.trigger( "ajaxComplete" , [xml, s] ); // Handle the global AJAX counter if ( s.global && ! --jQuery.active ) jQuery.event.trigger( "ajaxStop" ); // Process result if ( s.complete ) s.complete(xml, status); jQuery(io).unbind() setTimeout( function () { try { $(io).remove(); $(form).remove(); } catch (e) { jQuery.handleError(s, xml, null , e); } }, 100) xml = null } } // Timeout checker if ( s.timeout > 0 ) { setTimeout( function (){ // Check to see if the request is still happening if ( !requestDone ) uploadCallback( "timeout" ); }, s.timeout); } try { // var io = $('#' + frameId); var form = $( '#' + formId); $(form).attr( 'action' , s.url); $(form).attr( 'method' , 'POST' ); $(form).attr( 'target' , frameId); if (form.encoding) { form.encoding = 'multipart/form-data' ; } else { form.enctype = 'multipart/form-data' ; } $(form).submit(); } catch (e) { jQuery.handleError(s, xml, null , e); } if (window.attachEvent){ document.getElementById(frameId).attachEvent( 'onload' , uploadCallback); } else { document.getElementById(frameId).addEventListener( 'load' , uploadCallback, false ); } return {abort: function () {}}; }, uploadHttpData: function ( r, type ) { var data = !type; data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context if ( type == "script" ) jQuery.globalEval( data ); // Get the JavaScript object, if JSON is used. if ( type == "json" ) eval( "data = " + data ); // evaluate scripts within html if ( type == "html" ) jQuery( "<div>" ).html(data).evalScripts(); //alert($('param', data).each(function(){alert($(this).attr('value'));})); return data; } }) |
[转]一个文件上传的jquery插件的更多相关文章
- 强大的支持多文件上传的jQuery文件上传插件Uploadify
支持多文件上传的jQuery文件上传插件Uploadify,目前此插件有两种版本即Flash版本和HTML5版本,对于HTML5版本会比较好的支持手机浏览器,避免苹果手机Safari浏览器不支持Fla ...
- 利用Bootstrap简单实现一个文件上传进度条
© 版权声明:本文为博主原创文章,转载请注明出处 说明: 1. 使用commons-fileupload.jar实现文件上传及进度监听 2. 使用bootstrap的进度条进行页面显示 3. 因为进度 ...
- 文件上传利器JQuery上传插件Uploadify
在做日常项目中,经常在后台需要上传图片等资源文件,之前使用过几次这个组件,感觉非常好用 ,但是每次使用的时候都是需要经过一番查阅,所以还不如记住在这里,以后使用的时候就翻翻. 他的官方网站如下:htt ...
- 【文件上传】jquery之ajaxfileupload异步上传插件
来自:http://www.blogjava.net/sxyx2008/archive/2010/11/02/336826.html 由于项目需求,在处理文件上传时需要使用到文件的异步上传.这里使用J ...
- ASP.NET- 无刷新上传使用jQuery插件之ajaxFileUpload
灰常好,我已经使用过里面的代码了,可以用,原文地址:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html 一.ajaxFil ...
- MVC文件上传 - 使用jquery异步上传并客户端验证类型和大小
本篇体验MVC上传文件,从表单上传过渡到jquery异步上传. MVC最基本的上传文件是通过form表单提交方式 □ 前台视图部分 <% using(Html.BeginForm("F ...
- MVC文件上传-使用jQuery.FileUpload和Backload组件实现文件上传
本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: 处理文件上传的服务端组件Backload 用于处理文件上传的服务端组件 ...
- 基于Ajax的文件上传使用FileInput插件(使用谷歌翻译作者的原文,大致意思是对的,自己把握)
bootstrap-fileinput 说明文档:http://plugins.krajee.com/file-input 有许多人希望学习使用bootstrap-fileinput jQuery插件 ...
- springboot中使用分页,文件上传,jquery的具体步骤(持续更新)
分页: pom.xml 加依赖 <dependency> <groupId>com.github.pagehelper</groupId> <arti ...
随机推荐
- 特殊的Josn格式
static void Main(string[] args) { YtRequest<RequestHead, RequestBody> Ytrequ ...
- ios block和函数的区别
block是封装了一段代码的OC对象,可以被设为Property, 在调用block的地方block都会被替换成相应的代码,相当于内联函数. 函数可以使代码更加整洁易读,使用block会使代码可读性变 ...
- 一个最简单的登录页面测试case
具体需求: 有一个登陆页面, (假如上面有2个textbox, 一个提交按钮. 请针对这个页面设计30个以上的testcase.) 此题的考察目的:面试者是否熟悉各种测试方法,是否有丰富的Web测试经 ...
- LinQ 基础
LinQ全名:Linq to Sql,是一种数据库访问技术 常见的数据库访问技术: 1.ADO.NET 2.Entity Framework 框架 3.LinQ LinQ是高集成化的数据访问类,它会 ...
- js导入外部脚本文件
JS 语言没找到导入外部脚本文件的功能,只能通知宿主程序来处理. function include(path){ var a=document.createElement("script&q ...
- Object转bigdecimal
/*由数字字符串构造BigDecimal的方法 *设置BigDecimal的小数位数的方法 */ import java.math.BigDecimal; //数字字符串 String StrBd=& ...
- 根据关键词kill进程
#!/bin/sh pid=`ps -ef | grep /usr/bin/memcached | grep -v grep | awk '{print $2}'` kill $pid
- POJ 1228 - Grandpa's Estate 稳定凸包
稳定凸包问题 要求每条边上至少有三个点,且对凸包上点数为1,2时要特判 巨坑无比,调了很长时间= = //POJ 1228 //稳定凸包问题,等价于每条边上至少有三个点,但对m = 1(点)和m = ...
- 如果页面引用了外部JS代码,会被IE缓存的解决方法
在使用jquery时特别常见,明明修改的js,但是经常不生效,因为缓存,解决办法就是清除ie缓存,每次去点ie选项,太麻烦,网上有人用批处理去,还是每次去点,在页面中加入下面几行,就可以禁用缓存 &l ...
- HttpURLConnection请求网络数据
//使用线程 new Thread(){ public void run() { try { //先创建出了一 ...