页面结构
html部分
<input
type="file"
name="file"
id="input1"
/>
<button id="btn">取消上传</button>
<img src="" alt="" id="img" style="display: none" />
模拟上传
const myFile = document.querySelector('#input1')
const btn = document.querySelector('#btn')
const myImg = document.querySelector('#img')
let cancelUpload = null
function changeHandle() {
if (!myFile.files.length) {
return
}
const file = myFile.files[0]
if (!validateFile(file)) return
const reader = new FileReader()
reader.onload = e => {
myImg.src = reader.result
}
reader.readAsDataURL(file)
cancelUpload = upload(
file,
function (val) {
setProgress(val)
},
function (resp) {
console.log(resp)
myImg.style.display = 'block'
}
)
}
function validateFile(file) {
const sizeLimit = 1 * 1024 * 1024
const fileType = ['.jpg', '.png', 'jpeg', '.webp', 'gif']
if (file.size > sizeLimit) {
alert('文件尺寸过大')
return
}
const name = file.name.toLowerCase()
if (!fileType.some(e => name.endsWith(e))) {
alert('文件格式不对')
return
}
return true
}
function setProgress(val) {
console.log(val)
}
function upload(file, onProgress, onFinish) {
let p = 0
onProgress(p)
const timer = setInterval(() => {
p += 2
onProgress(p)
if (p >= 100) {
onFinish('上传结束,服务器返回的结果')
clearInterval(timer)
}
}, 50)
return function () {
clearInterval(timer)
}
}
function cancel() {
cancelUpload && cancelUpload()
myFile.value = null
}
btn.addEventListener('click', cancel)
XMLHttpRequest上传文件(以下的上传文件方法看服务器端给出的要求来)
function upload(file, onProgress, onFinish){
onProgress(0)
const xhr = new XMLHttpRequest()
const form = new FormData()
form.append('avatar',file)
xhr.open('POST','http://test.com:9527/upload/single')
xhr.onload = function(){
const resp = JSON.parse(xhr.responseText)
onFinish(resp)
}
xhr.onerror = function(e){
alert('请求失败',e)
}
xhr.timeout = 10000;
xhr.ontimeout = function(event){
alert('请求超时!');
}
xhr.upload.onprogress = e => {
const percent = Math.floor((e.loaded / e.total) * 100)
onProgress(percent)
}
xhr.send(form)
return function() {
xhr.abort()
}
}
base64上传文件
function uploadBase64(file, onProgress, onFinish) {
const reader = new FileReader()
reader.onload = function (e) {
onProgress(0)
const xhr = new XMLHttpRequest()
const ext = '.' + file.type.split('/').at(-1)
const base64 = e.target.result.split('.').pop()
xhr.open('POST', 'http://test.com:9527/upload/single')
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.onload = function () {
const resp = JSON.parse(xhr.responseText)
onFinish(resp)
}
xhr.onerror = function (e) {
alert('请求失败', e)
}
xhr.timeout = 10000;
xhr.ontimeout = function(event){
alert('请求超时!');
}
xhr.upload.onprogress = e => {
const percent = Math.floor((e.loaded / e.total) * 100)
onProgress(percent)
}
xhr.send(
JSON.stringify({
ext,
avatar: base64,
})
)
}
reader.readAsDataURL(file)
return function () {
xhr && xhr.abort()
}
}
拖拽上传
新增html部分
<style>
.drag::before {
content: '+';
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
font-size: 80px;
transform: translate(-50%, -50%);
color: rgba(0, 0, 0, 0.2);
}
.drag input {
position: absolute;
left: 0;
width: 100%;
height: 100%;
}
</style>
<div
class="drag"
style="
position: relative;
width: 200px;
height: 200px;
border: 1px solid #270ab6;
text-align: center;
line-height: 200px;
cursor: pointer;
"
>
拖动文件到此上传
</div>
js部分
const dragDiv = document.querySelector('.drag')
const dragFile = document.querySelector('#dragFile')
dragDiv.addEventListener('dragenter', e => {
e.preventDefault()
})
dragDiv.addEventListener('dragover', e => {
e.preventDefault()
})
dragDiv.addEventListener('drop', e => {
e.preventDefault()
const form = e.dataTransfer.files
console.log(e.dataTransfer);
if (!e.dataTransfer.types.includes('Files')) {
alert('仅支持拖拽文件')
return
}
if (form.length > 1) {
alert('仅支持上传一个文件')
return
}
myFile.files = form
changeHandle()
})
dragFile.addEventListener('change', e => {
myFile.files = e.target.files
changeHandle()
})