这篇文章主要介绍了使用ajaxfileupload.js实现ajax上传文件php版,需要的朋友可以参考下

 无论是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代码类似:

<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脚本:

<?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插件:

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',

后台处理脚本为:

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:ToolsxampptmpphpED45.tmp',
  'error' => 0,
  'size' => 250,
  ),
  0 =>
  array (
  'test' => 'test',
  'ok' => 'ok',
  'PHPSESSID' => 'e379fd4fb2abca6e802a1302805a5535',
  ),
)

ajaxfileupload.js:

jQuery.extend({  createUploadIframe: function(id, uri) {  //create framevar 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 notmodifiedif ( 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 dataif ( s.success )s.success( data, status );// Fire the global callbackif( s.global )jQuery.event.trigger( "ajaxSuccess", [xml, s] );} elsejQuery.handleError(s, xml, status);} catch(e)  {status = "error";jQuery.handleError(s, xml, status, e);} // The request was completedif( s.global )jQuery.event.trigger( "ajaxComplete", [xml, s] ); // Handle the global AJAX counterif ( s.global && ! --jQuery.active )jQuery.event.trigger( "ajaxStop" ); // Process resultif ( 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 happeningif( !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;  }}) 
最新资讯
特斯拉汽车第三季度营收87.71亿美元 净利同比大增131%

特斯拉汽车第三季度营

特斯拉汽车第三季度总营收为87.71亿美元,比去年同期的6
用“二次号”被欠贷:运营商别让用户为衍生问题买单

用“二次号”被欠贷:运

用“二次号”莫名被欠贷或没法注册12306,这些用户困扰
美团七年扶贫样本:马背上的少年成今日骑手

美团七年扶贫样本:马背

骑手工作的技能门槛相对较低,灵活性强,能在较短时间里提
猿辅导22亿美元新一轮融资已交割?猿辅导:近期将披露融资信息

猿辅导22亿美元新一轮

10月21日有媒体报道称,猿辅导在线教育22亿美元新一轮融
A股首个万亿互联网巨头来了!蚂蚁集团最新估值2.1万亿元

A股首个万亿互联网巨

国信证券通过绝对估值法和相对估值法,给出的估值范围是
证监会同意 蚂蚁来A股上“树”了!

证监会同意 蚂蚁来A股

港股IPO进入倒计时之后,蚂蚁集团也正式拿到了A股的“入
最新文章
详解Vue的ref特性的使用

详解Vue的ref特性的使

这篇文章主要介绍了详解Vue的ref特性的使用,文中通过
vue学习笔记之slot插槽基本用法实例分析

vue学习笔记之slot插

这篇文章主要介绍了vue学习笔记之slot插槽基本用法,结
vue跳转方式(打开新页面)及传参操作示例

vue跳转方式(打开新页

这篇文章主要介绍了vue跳转方式(打开新页面)及传参操作,
vue学习笔记之过滤器的基本使用方法实例分析

vue学习笔记之过滤器

这篇文章主要介绍了vue学习笔记之过滤器的基本使用方
js获取本日、本周、本月的时间代码

js获取本日、本周、本

本篇文章给大家分享的内容是利用js如何获取本日、本周
node crawler如何添加promise支持

node crawler如何添加

这篇文章主要介绍了node crawler如何添加promise支持,