js 实现文件上传预览(学习)
1. 实现方式
1.1 基于http/2.0 传输协议达到的效果 即一次连接多次通讯
1.2 依靠js提供的api,FormData来实现获取二进制流文件
1.3 依靠js提供的api,XMLHttpRequest发送请求
1.4 依靠js提供的api,FileReader实现本地预览
2. JS API —— formData
2.1formData是一个对象,在html的form表单触发提交后,可以通过formData来接受,其对应的数据会存储进去
// 先写个简单的表单标签,输入值并获取到form对象执行下面代码
let form = document.querySelector('form')
form.onsubmit = (e)=>{
e.preventDefault()
const fd = new FormData(form)
// 打印只能显示这个对象上的方法,看不到实际传输的数据,需要遍历或者对应api来查看
console.log(fd)
}
2.2 formdata的api
const fd = new FromData('form')
// 加入一条数据;key存在时会追加进去
fd.append(key,value)
// get返回第一个值;getAll返回所有值是个数组
fd.get('key')/getAll('key')
// 删除指定键
fd.delete()
// 设置属性值,如果对应的属性值存在则覆盖原值,否则新增一项属性值。
fd.set()
// 方法会返回一个布尔值,表示是否存在这个key
fd.has()
// 返回一个iterator对象,可以遍历访问键值对,值可以是一个 USVString , 或者 Blob对象
const iterator = fd.entries()
iterator.next(); // {done:false, value:["key1", "value1"]}
iterator.next(); // {done:fase, value:["key2", "value2","key2", "value3",]}
iterator.next(); // {done:true, value:undefined}
// 返回所有键
fd.keys()
// 返回所有值的iterator对象
fd.values()
3. JS API —— FileReader
FileReader结合input:file可以很方便的异步读取本地文件;案例
选择头像:<input type="file" name="avatar" multiple='multiple' class="file"/>
file.addEventListener('change',function(){
const rd = new FileReader()
rd.readAsDataURL(file.files[0])
rd.onload = function(res){
console.log('当读取操作成功完成时调用')
}
rd.onprogress = function(res){
console.log('在读取数据过程中周期性(每50ms)调用')
}
rd.onloadend = function(res){
console.log('当读取操作完成时调用,无论成功或失败')
}
rd.onabort = function(res){
console.log('当读取操作被中止时调用')
}
rd.onerror = function(res){
console.log('当读取操作发生错误时调用')
}
rd.onloadstart = function(res){
console.log('当读取操作开始时调用')
}
})
4. 本地上传预览 案例
4.1 打开phpstudy 启动apache
4.2 vscode打开服务端目录在里边新建文件(就是默认的www的目录,客户端上有入口)
4.3 新建upload.php
<?php
header('content-type:text/html;charset=utf-8');
// 参数(要移动的临时文件,移动到哪里)
move_uploaded_file($_FILES['avatar']['tmp_name'],'./test.gif');
// 返回给前端的数据
$arr = array(
"message" => "success",
// $_POST从前端发送的其他数据会存在这里也是关联型数组
"data" => $_POST,
// $_FILES专门用来接受file文件的关联型数组
"files" => $_FILES,
"url" => "/upload/test.gif"
);
echo json_encode($arr)
?>
4.4 新建upload.html
<meta charset="UTF-8">
<form>
<label>
<img id="avatar" src="#" alt="avatar">
选择头像:<input type="file" name="avatar" multiple='multiple' class="file"/>
</label>
<br>
<label>
账户名:<input type="text" name="username"/>
</label>
<br>
<label>
密码:<input type="password" name="password"/>
</label>
<br>
<input type="submit" value="submit">
</form>
<script>
const form = document.querySelector('form')
const file = document.querySelector('.file')
const img = document.querySelector('#avatar')
// 文件上传
form.addEventListener('submit',function(e){
e.preventDefault()
const fd = new FormData(form)
console.log(fd.getAll('avatar'))
const xhr = new XMLHttpRequest()
xhr.open('post','./upload.php')
xhr.send(fd)
xhr.onload = function(){
console.log(JSON.parse(xhr.responseText))
}
})
// 本地预览
file.addEventListener('change',function(){
const rd = new FileReader()
rd.readAsDataURL(file.files[0])
rd.onload = function(res){
img.src = res.target.result
}
})
</script>
4.5 执行html,从localhost进入,选择文件上传后就能看到文件已经在当前目录了。
以上