無(wú)刷新上傳的方法很多,比如:
- 利用現(xiàn)代瀏覽器的FormData掖桦。
- 利用現(xiàn)代瀏覽器的FileReader將圖片文件編程base64編碼荧呐。
- 利用類(lèi)庫(kù)(如jQuery)的ajax纷捞。
- 利用iframe祠肥。
最近接到一個(gè)項(xiàng)目要求兼容IE8+武氓,沒(méi)有選擇余地,只能用iframe了搪柑。原理如下:
<form action="upload.php" target="iframe" method="post" entype="mutipart/form-data">
<input type="file" name="file"/>
<iframe name="iframe" class="hide">
</iframe>
</form>
這上述代碼里聋丝,最重要得就是** target="file" **索烹。它實(shí)現(xiàn)了使用隱藏的iframe上傳文件工碾。
這樣,我們就可以在上傳文件后返回給iframe結(jié)果百姓,再用js解析iframe里的內(nèi)容--或者是顯示圖片渊额,或者是顯示提示信息。
代碼如下:
/**
* 利用隱藏iframe無(wú)刷新上傳圖片
* usage:
* var widget = new IframeUpload({
container:'.container',//上傳的組件(帶+號(hào)的div)要放在哪個(gè)類(lèi)或者id里垒拢,隱藏的input也放在這里
uploadUrl:'upload.php',
deleteUrl:'delete.php',
deleteMethod:'post',//可以不寫(xiě)旬迹,默認(rèn)是post
max:5//最多上傳幾張圖片
});
* @type {Class}
*/
var IframeUpload = new Class({
count:0,//記錄目前頁(yè)面上存在的iframe
initialize:function(options){
var othis = this;
var defaultOptions = {
container:"file",
marginRight:10,//upload widget 間隔
className:'iframe-upload-widget',//給adopt進(jìn)頁(yè)面的form加一個(gè)類(lèi),最后刪除
max:5,
interval:50,
ajaxName:'file',//iframe 上傳圖片時(shí)求类,圖片的name
imageName:'file[]',//最后一次性上傳圖片時(shí)圖片的name
uploadUrl:"upload.php",
method:'post',//upload method
deleteUrl:'',
deleteMethod:'post',
deleteTag:'id',//刪除一張圖片時(shí)奔垦,指定隱藏input的name
enctype:"multipart/form-data",
onSuccess:function(html){
//console.log(html)
// var othis = this.self;
var arr = html.split(";");
if(arr.length == 2){
this.appendImage(arr[0]);
this.setValue(arr[1]);
}else{
Dialog.alert(html);
}
}
};
if(typeOf(options) == "object"){
var opt = this.opt = Object.merge(defaultOptions,options);
}else{
var opt = this.opt = defaultOptions;
}
var classOrId = opt.container;
var first = classOrId.substring(0,1);
if(first == "."){
othis.container = $$(classOrId);
}else if(first == "#"){
alert("container can not start with #");
}else{
othis.container = $(classOrId);
}
othis.init();
},
init:function(){
this.createInput();
},
clear:function(){
var othis = this;
$$("."+othis.opt.className).dispose();
},
getIframeBody:function(iframe){
return iframe.contentWindow.document.body;
},
listen:function(iframe,input,wrap,tagIdInput){
var othis = this;
var opt = othis.opt;
var timeout = setInterval(function(){
var html = othis.getIframeBody(iframe).innerHTML.trim();
if(html != ""){
othis.getIframeBody(iframe).innerHTML = "";
clearInterval(timeout);
if(othis.count < opt.max){
othis.createInput();
}
opt.onSuccess.bind({
self:othis,
setValue:function(value){
input.set("value",value);
tagIdInput.set("value",value);
},
appendImage:function(imageUrl){
othis.appendImage(wrap,imageUrl);
},
input:input,
tagInput:tagIdInput,
div:wrap
})(html);
}
},opt.interval);
},
uuid:function(num){
var letters = ['a','b','c','d','e','f','g','h','i','1','2','3','4','5','6','7','8','9'];
if(typeOf(num) != "number"){
num = 8;
}
var code = "";
for(var i = 0;i<num;i++){
code += letters.getRandom();
}
return code;
},
appendImage:function(wrap,imageUrl){
wrap.setStyle("background-image","url("+imageUrl+")");
},
createInput:function(){
var othis = this;
var opt = othis.opt;
othis.count ++;
var iframeName = othis.uuid();
var mapId = othis.uuid();//upload div 上綁定mapId,通過(guò)這個(gè)id找到對(duì)應(yīng)的隱藏input
var wrap,form,input,iframe,tagIdInput,hiddenInput;
input = new Element("input",{
type:'file',
name:opt.ajaxName,
events:{
'change':function(){
form.submit();
othis.listen(iframe,hiddenInput,wrap,tagIdInput);
}
}
});
wrap = new Element("div",{
'data-mapid':mapId,
styles:{
width:70,
height:70,
marginRight:opt.marginRight,
position:'relative',
display:'inline-block',
backgroundColor:"#efefef",
color:"#ddd",
border:'1px solid #ddd',
textAlign:'center',
fontSize:13,
backgroundRepeat:'no-repeat',
backgroundSize:'contain',
backgroundPosition:'center'
},
html:"<span style='font-size:25px'>+</span><p style='margin-top:10px'>上傳圖片</p>",
events:{
'click':function(){
input.click();
},
},
});
form = new Element("form",{
action:opt.uploadUrl,
method:opt.method,
target:iframeName,
enctype:opt.enctype,
'class':opt.className,
styles:{
display:"none"
}
});
iframe = new Element("iframe",{
name:iframeName,
styles:{
display:'none'
}
});
tagIdInput = new Element("input",{
name:opt.deleteTag,
styles:{
display:'none',
}
});
//用于最后上傳的input
hiddenInput = new Element("input",{
type:'hidden',
'data-index':1,
id:mapId,
name:opt.imageName,
});
if(othis.count > 1){
var deleteIcon = new Element("span",{
styles:{
position:"absolute",
right:-8,
top:-8,
borderRadius:'50%',
textAlign:'center',
lineHeight:18,
width:16,
height:16,
border:'1px solid #333',
backgroundColor:'#efefef',
color:'red',
cursor:'pointer',
},
html:'×',
events:{
click:function(e){
e.stop();
if(opt.deleteUrl){
var data = opt.deleteTag+"="+hiddenInput.get("value");
new Request({
url:opt.deleteUrl,
'data':data,
method:opt.deleteMethod
}).send();
}
hiddenInput.dispose();
wrap.dispose();
othis.count --;
}
}
});
wrap.adopt(deleteIcon);
}
form.adopt(input,iframe,tagIdInput);
$$(document.body).adopt(form);
othis.container.adopt(wrap,hiddenInput);
},
});
后端php對(duì)應(yīng)的代碼:
#file upload.php
<?php
$file = $_FILES;
$f = $file['file'];
move_file_upload($f['tmp_name'],"test.jpg");
$id = uniqid();
echo "http://localhost/test.jpg;".$id;