本用例主要含兩個文件(index.html、submit_form_process.php),一個文件夾(files/)。特別的,files中含一個報錯圖片error.jpg,jquery庫引用了外鏈。
1、index.html文件
功能:點擊圖片添加文件、添加多個文件、即時上傳文件、顯示上傳文件反饋信息。
包含技術:
1)$.ajax
2)$.ajax 發送FormData對象
3)input multiple="multiple"上傳多個文件
4)img onclick="getElementById('inputfile').click()" 點擊圖片實現添加文件操作
5)input type="file" 樣式:height:0;width:0;z-index: -1;隱藏添加文件按鈕(Chrome下使用display:none會導致點擊失效)
源碼:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>Easy Ajax FormData Upload Multiple Images</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <meta http-equiv="Content-Language" content="zh-CN" /> 7 <script type="text/javascript" src="http://files.cnblogs.com/Zjmainstay/jquery-1.6.2.min.js"></script> 8 </head> 9 <body> 10 <style> 11 #feedback{width:1200px;margin:0 auto;} 12 #feedback img{float:left;width:300px;height:300px;} 13 #ZjmainstaySignaturePicture,#addpicContainer{float:left;width: 100%;} 14 #addpicContainer{margin-left:5px;} 15 #ZjmainstaySignaturePicture img{width: 535px;} 16 #addpicContainer img{float: left;} 17 .loading{display:none;background:url("http://f7-preview.awardspace.com/zjmainstay.co.cc/jQueryExample/jquery_upload_image/files/ui-anim_basic_16x16.gif") no-repeat scroll 0 0 transparent;float: left;padding:8px;margin:18px 0 0 18px;} 18 </style> 19 <div id="ZjmainstaySignaturePicture"><a href="http://www.cnblogs.com/Zjmainstay"><img src="http://pic002.cnblogs.com/images/2012/383557/2012071311244097.jpg"/></a></div> 20 <div id="addpicContainer"> 21 <!-- 利用multiple="multiple"屬性實現添加多圖功能 --> 22 <!-- position: absolute;left: 10px;top: 5px;只針對本用例將input隱至圖片底下。--> 23 <!-- height:0;width:0;z-index: -1;是為了隱藏input,因為Chrome下不能使用display:none,否則無法添加文件 --> 24 <!-- onclick="getElementById('inputfile').click()" 點擊圖片時則點擊添加文件按鈕 --> 25 <img onclick="getElementById('inputfile').click()" style="cursor:pointer;border: 1px solid #AABBCC;" title="點擊添加圖片" alt="點擊添加圖片" src="http://f7-preview.awardspace.com/zjmainstay.co.cc/jQueryExample/jquery_upload_image/files/addfile.jpg"> 26 <input type="file" multiple="multiple" id="inputfile" style="height:0;width:0;z-index: -1; position: absolute;left: 10px;top: 5px;"/> 27 <span class="loading"></span> 28 </div> 29 <div id="feedback"></div> <!-- 響應返回數據容器 --> 30 <script type="text/javascript"> 31 $(document).ready(function(){ 32 //響應文件添加成功事件 33 $("#inputfile").change(function(){ 34 //創建FormData對象 35 var data = new FormData(); 36 //為FormData對象添加數據 37 $.each($('#inputfile')[0].files, function(i, file) { 38 data.append('upload_file'+i, file); 39 }); 40 $(".loading").show(); //顯示加載圖片 41 //發送數據 42 $.ajax({ 43 url:'submit_form_process.php', 44 type:'POST', 45 data:data, 46 cache: false, 47 contentType: false, //不可缺參數 48 processData: false, //不可缺參數 49 success:function(data){ 50 data = $(data).html(); 51 //第一個feedback數據直接append,其他的用before第1個( .eq(0).before() )放至最前面。 52 //data.replace(/</g,'<').replace(/>/g,'>') 轉換html標簽,否則圖片無法顯示。 53 if($("#feedback").children('img').length == 0) $("#feedback").append(data.replace(/</g,'<').replace(/>/g,'>')); 54 else $("#feedback").children('img').eq(0).before(data.replace(/</g,'<').replace(/>/g,'>')); 55 $(".loading").hide(); //加載成功移除加載圖片 56 }, 57 error:function(){ 58 alert('上傳出錯'); 59 $(".loading").hide(); //加載失敗移除加載圖片 60 } 61 }); 62 }); 63 }); 64 </script> 65 </body> 66 </html>
2、submit_form_process.php后台處理文件
功能:對FormData中包含的$_FILES數組做處理並上傳圖片文件,回傳反饋信息。
包含技術:
1)FormData提交至$_FILES后的結構形式
2)iconv('utf-8','gb2312',$filename) 對文件名進行轉碼處理
3)preg_match("/^\.(jpg|jpeg|gif|png){1}$/i", strrchr($gb_filename, '.')) 文件類型過濾
4)move_uploaded_file()上傳文件
5)echo '<textarea><img....<img....</textarea>';回傳反饋信息。
源碼:
1 <?php 2 header('content-type:text/html charset:utf-8'); 3 $dir_base = "./files/"; //文件上傳根目錄 4 //沒有成功上傳文件,報錯並退出。 5 if(empty($_FILES)) { 6 echo "<textarea><img src='{$dir_base}error.jpg'/></textarea>"; 7 exit(0); 8 } 9 10 $output = "<textarea>"; 11 $index = 0; //$_FILES 以文件name為數組下標,不適用foreach($_FILES as $index=>$file) 12 foreach($_FILES as $file){ 13 $upload_file_name = 'upload_file' . $index; //對應index.html FomData中的文件命名 14 $filename = $_FILES[$upload_file_name]['name']; 15 $gb_filename = iconv('utf-8','gb2312',$filename); //名字轉換成gb2312處理 16 //文件不存在才上傳 17 if(!file_exists($dir_base.$gb_filename)) { 18 $isMoved = false; //默認上傳失敗 19 $MAXIMUM_FILESIZE = 1 * 1024 * 1024; //文件大小限制 1M = 1 * 1024 * 1024 B; 20 $rEFileTypes = "/^\.(jpg|jpeg|gif|png){1}$/i"; 21 if ($_FILES[$upload_file_name]['size'] <= $MAXIMUM_FILESIZE && 22 preg_match($rEFileTypes, strrchr($gb_filename, '.'))) { 23 $isMoved = @move_uploaded_file ( $_FILES[$upload_file_name]['tmp_name'], $dir_base.$gb_filename); //上傳文件 24 } 25 }else{ 26 $isMoved = true; //已存在文件設置為上傳成功 27 } 28 if($isMoved){ 29 //輸出圖片文件<img>標簽 30 //注:在一些系統src可能需要urlencode處理,發現圖片無法顯示, 31 // 請嘗試 urlencode($gb_filename) 或 urlencode($filename),不行請查看HTML中顯示的src並酌情解決。 32 $output .= "<img src='{$dir_base}{$filename}' title='{$filename}' alt='{$filename}'/>"; 33 }else { 34 $output .= "<img src='{$dir_base}error.jpg' title='{$filename}' alt='{$filename}'/>"; 35 } 36 37 $index++; 38 } 39 40 echo $output."</textarea>"; 41 42 //End_php
——————————————————————————————————————————————————————————————————————————————————
兼容IE實現(謝謝@園丁8899的提問)
1、index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>Easy Ajax FormData Upload Multiple Images</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <meta http-equiv="Content-Language" content="zh-CN" /> 7 <script type="text/javascript" src="http://files.cnblogs.com/Zjmainstay/jquery-1.6.2.min.js"></script> 8 </head> 9 <body> 10 <style> 11 #feedback{width:1200px;margin:0 auto;} 12 #feedback img{float:left;max-width:300px;max-height:300px;} 13 #ZjmainstaySignaturePicture,#addpicContainer{float:left;width: 100%;} 14 #addpicContainer{margin-left:5px;} 15 #ZjmainstaySignaturePicture img{width: 535px;} 16 #addpicContainer img{float: left;} 17 .loading{display:none;background:url("files/loading.gif") no-repeat scroll 0 0 transparent;float: left;padding:8px;margin:18px 0 0 18px;} 18 </style> 19 <div id="ZjmainstaySignaturePicture"><a href="http://www.cnblogs.com/Zjmainstay"><img src="http://pic002.cnblogs.com/images/2012/383557/2012071311244097.jpg"/></a></div> 20 <div id="addpicContainer"> 21 <!-- 利用multiple="multiple"屬性實現添加多圖功能 --> 22 <!-- position: absolute;left: 10px;top: 5px;只針對本用例將input隱至圖片底下。--> 23 <!-- height:0;width:0;z-index: -1;是為了隱藏input,因為Chrome下不能使用display:none,否則無法添加文件 --> 24 <!-- onclick="getElementById('inputfile').click()" 點擊圖片時則點擊添加文件按鈕 --> 25 <img onclick="getElementById('inputfile').click()" style="cursor:pointer;border: 1px solid #AABBCC;" title="點擊添加圖片" alt="點擊添加圖片" src="files/addfile.jpg"> 26 <input type="file" multiple="multiple" id="inputfile" style="height:0;width:0;z-index: -1; position: absolute;left: 10px;top: 5px;"/> 27 <span class="loading"></span> 28 </div> 29 <div id="feedback"></div> <!-- 響應返回數據容器 --> 30 <script type="text/javascript"> 31 $(document).ready(function(){ 32 //成功回調函數抽取出來 33 var successHandler = function(data){ 34 data = $(data).html(); 35 //第一個feedback數據直接append,其他的用before第1個( .eq(0).before() )放至最前面。 36 //data.replace(/</g,'<').replace(/>/g,'>') 轉換html標簽,否則圖片無法顯示。 37 if($("#feedback").children('img').length == 0) $("#feedback").append(data.replace(/</g,'<').replace(/>/g,'>')); 38 else $("#feedback").children('img').eq(0).before(data.replace(/</g,'<').replace(/>/g,'>')); 39 $(".loading").hide(); //加載成功移除加載圖片 40 } 41 42 if(typeof(FormData) != 'function'){ 43 var formHtml = '<iframe id="uploadIframe" name="uploadIframe" style="display:none;"></iframe>' 44 +'<form action="submit_form_process.php" method="post" target="uploadIframe" name="uploadForm" id="uploadForm" enctype="multipart/form-data">' 45 +'<input type="file" id="inputfile" name="upload_file" style="float:left;"/>' 46 +'<input type="hidden" name="isIE" value="1"/></form>'; 47 $("#inputfile,#addpicContainer>img").remove(); 48 $("#addpicContainer").append(formHtml); 49 $("#uploadIframe").load(function(){ 50 var data = $(window.frames['uploadIframe'].document.body).find("textarea"); 51 successHandler(data); 52 }); 53 } 54 55 //響應文件添加成功事件 56 $("#inputfile").change(function(){ 57 if(typeof(FormData) != 'function'){ 58 $("#uploadForm").submit(); 59 }else { 60 //創建FormData對象 61 var data = new FormData(); 62 //為FormData對象添加數據 63 $.each($('#inputfile')[0].files, function(i, file) { 64 data.append('upload_file'+i, file); 65 }); 66 $(".loading").show(); //顯示加載圖片 67 //發送數據 68 $.ajax({ 69 url:'submit_form_process.php', 70 type:'POST', 71 data:data, 72 cache: false, 73 contentType: false, //不可缺參數 74 processData: false, //不可缺參數 75 success: successHandler, 76 error:function(){ 77 alert('上傳出錯'); 78 $(".loading").hide(); //加載失敗移除加載圖片 79 } 80 }); 81 } 82 }); 83 }); 84 </script> 85 </body> 86 </html>
2、submit_form_process.php
1 <?php 2 $dir_base = "./files/"; //文件上傳根目錄 3 //沒有成功上傳文件,報錯並退出。 4 if(empty($_FILES)) { 5 echo "<textarea><img src='{$dir_base}error.jpg'/></textarea>"; 6 exit(0); 7 } 8 9 $output = "<textarea>"; 10 $index = 0; //$_FILES 以文件name為數組下標,不適用foreach($_FILES as $index=>$file) 11 foreach($_FILES as $file){ 12 if($_POST['isIE']) { 13 $upload_file_name = 'upload_file'; //對應index.html中的文件命名(IE) 14 }else { 15 $upload_file_name = 'upload_file' . $index; //對應index.html FomData中的文件命名(其他) 16 } 17 $filename = $_FILES[$upload_file_name]['name']; 18 $gb_filename = iconv('utf-8','gb2312',$filename); //名字轉換成gb2312處理 19 //文件不存在才上傳 20 if(!file_exists($dir_base.$gb_filename)) { 21 $isMoved = false; //默認上傳失敗 22 $MAXIMUM_FILESIZE = 1 * 1024 * 1024; //文件大小限制 1M = 1 * 1024 * 1024 B; 23 $rEFileTypes = "/^\.(jpg|jpeg|gif|png){1}$/i"; 24 if ($_FILES[$upload_file_name]['size'] <= $MAXIMUM_FILESIZE && 25 preg_match($rEFileTypes, strrchr($gb_filename, '.'))) { 26 $isMoved = @move_uploaded_file ( $_FILES[$upload_file_name]['tmp_name'], $dir_base.$gb_filename); //上傳文件 27 } 28 }else{ 29 $isMoved = true; //已存在文件設置為上傳成功 30 } 31 if($isMoved){ 32 //輸出圖片文件<img>標簽 33 //注:在一些系統src可能需要urlencode處理,發現圖片無法顯示, 34 // 請嘗試 urlencode($gb_filename) 或 urlencode($filename),不行請查看HTML中顯示的src並酌情解決。 35 $output .= "<img src='{$dir_base}{$filename}' title='{$filename}' alt='{$filename}'/>"; 36 }else { 37 $output .= "<img src='{$dir_base}error.jpg' title='{$filename}' alt='{$filename}'/>"; 38 } 39 40 $index++; 41 } 42 43 echo $output."</textarea>"; 44 45 //End_php
軟件包下載:PHP jQuery多圖上傳實現源文件(兼容IE)
jQuery插件版本:jQuery插件版本(兼容IE)
本文結束之前特別感謝@東方翔在《用最簡單的例子實現jQuery圖片即時上傳》中評論提及Ajax FormData對象,這才有了本文用jQuery實現多圖上傳的實現。
PS:該吐槽的吐槽,該評論的評論,該推薦的推薦,該踩的地方踩兩腳——您的意見,是我完善的源泉。謝謝!