无刷新上传文件的2种方法

今天在网上刷到一篇文章《三种无刷新上传文件的方法》,于是自己亲手试了试,果然可行。自己只学会了其中的两种,就把自己尝试的demo和结果记录下来:
首先是第一种:
使用FormData上传文件,formdata可以封装form标签对象,其中对象中是以键值对的形式存在的。我们可以使用append方法来添加键值,如:
1
2
var oMyForm = new FormData();
oMyForm.append("name", "ZhangSan");
这里我就直接来上代码介绍如何使用formData来上传图片:
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form>
<input type="text" name="firstname">
<input type="file" id="file" name="file">
<button stye="submit" id="submit">提交</button>
</form>
<script>
document.getElementById('submit').onclick = function(event){
if(event.preventDefault){//取消按钮默认提交行为
event.preventDefault();
} else {
event.returnValue = false;
}
var formDOM = document.getElementsByTagName('form')[0];
var formData = new FormData(formDOM);//创建formData对象
var req = new XMLHttpRequest();
req.open("POST", "upload.php");//使用POST发送请求
req.onload = function(event){
if(this.status === 200){
console.log(this.response);//请求成功后打印返回的结果
}
}
req.send(formData);
req = null;
}
</script>
</body>
</html>

注释对代码进行了介绍,就是把formData通过ajax发到后端去。
然后php代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php	
$firstname = $_POST['firstname'];

$filename = time() . substr($_FILES['file']['name'], strrpos($_FILES['file']['name'],'.'));

$response = array();

if(move_uploaded_file($_FILES['file']['tmp_name'], $filename)){

$response['status'] = 1; //成功

$response['filename'] = $filename;

$response['firstname'] = $firstname;

} else {

$response['status'] = -1;

}

echo json_encode($response);
?>

这样就可以后端就会保存到图片了。以上,整个上传图片的流程结束。

接下来是使用iframe来无刷新上传文件的demo

普通的按钮,点击后页面会跳转到提交的地址,而这个地址是根据form标签的target属性指定的,所以只要我们创建个iframe标签,然后指定跳转到这个iframe地址就可以获取到后端返回的数据,也不用跳转页面了,拿到数据后,再把iframe删掉就可以了,具体代码如下:
HTML代码:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="upload1.php" method="post" enctype="multipart/form-data">
<input type="text" name="firstname">
<input type="file" id="file" name="file">
<input type="submit" id="submit" value="提交">
</form>
<script>
document.getElementById('submit').onclick = function(event){
var iframe = document.createElement("iframe");
iframe.width = 0;
iframe.height = 0;
iframe.border = 0;
iframe.name = "form-iframe";
iframe.id = "form-iframe";
iframe.setAttribute("style", "width:0;height:0;border:none");
this.form.appendChild(iframe);
this.form.target = "form-iframe";
iframe.onload = function(){
var img = document.createElement("img");
var responseData = this.contentDocument.body.textContent
|| this.contentWindow.document.body.textContent;
//获取iframe的内容,即服务返回的数据
var json = JSON.parse(responseData);//后端返回的json
console.log(json);
img.src = json.filename;
document.getElementsByTagName("form")[0].appendChild(img);//显示图片
setTimeout(function(){//删掉iframe
var _frame = document.getElementById("form-iframe");
_frame.parentNode.removeChild(_frame);
}, 100);
}
}
</script>
</body>
</html>

上面的按钮点击函数里,就是创建iframe标签,然后通过target属性指定到这个iframe,再在iframe的load函数里,或者后端返回的数据,拿到数据后,再删除iframe.
php代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php	
$firstname = $_POST['firstname'];

$filename = time() . substr($_FILES['file']['name'], strrpos($_FILES['file']['name'],'.'));

$response = array();

if(move_uploaded_file($_FILES['file']['tmp_name'], $filename)){

$response['status'] = 1; //成功

$response['filename'] = $filename;

$response['firstname'] = $firstname;

} else {

$response['status'] = -1;

}

echo json_encode($response);
?>

php后端代码和第一种没有什么区别,都是获取表单数据。