常用的两种本地文件上传方式是:
- 通过 input type="file" 选择本地文件
- 通过拖拽的方式
第一种方式最常用,代码如下:
html:
<form enctype="multipart/form-data" method="post">
<input type="file" id="file-input" name="fileContent">
</form>
js:
let file = document.getElementById('file-input')
file.onchange = function () {
let formData = new FormData(this.form)
// 上传数据
formData.append("fileName", this.value)
// FileReader可以读取文件的内容
let fileReader = new FileReader()
// 转换成base64编码
fileReader.readAsDataURL(this.files[0])
let fileType = this.files[0].type
fileReader.onload = function () {
if (/^image\[jpeg|png|gif]/.test(fileType)) {
console.log("result:", this.result)
}
}
}
第二种的拖拽方式在PC端很方便:
html:
<div class="img-box">
drop your image
</div>
js:
let img = document.getElementsByClassName('img-box')
img[0].ondragover = function (e) {
e.preventDefault()
}
img[0].ondrop = function (e) {
e.preventDefault()
let file = e.dataTransfer.files[0]
// 可以使用FileReader
let fileReader = new FileReader()
fileReader.readAsDaraURL(file)
// 或者添加到FormData
let formData = new FormData()
formData.append("file", file)
}
拿到了数据以后,我们可以得到:
- FormData格式的数据
- FileReader读取到的base64
let form = document.querySelector("form")
formData = new FormData(form)
formData.append("fileName", "photo")
let xhr = new XMLHttpRequest()
xhr.open("POST", "/upload")
xhr.send(formData)
如果用jQuery,要设置两个属性为false
$.ajax({
url: "/upload",
type: "POST",
data: formData,
processData: false, // 不处理数据
contentType: false // 不设置内容类型
})
因为jQuery会对内容进行转义,并且根据data自动设置请求mime类型
如果上传的数据是base64的话,可以把base64转换成blob,然后再append到一个formData里面。
// base64 转化为blob
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || ''
sliceSize = sliceSize || 512
let byteCharacters = atob(b64Data)
let byteArrays = []
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
let slice = byteCharacters.slice(offset, offset + sliceSize)
let byteNumbers = new Array(slice.length)
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
let byteArray = new Unit8Array(byteNumbers)
byteArrays.push(byteArray)
}
let blob = new Blob(byteArrays, {type: contentType})
return blob
}
然后就可以append到formData里面
let blob = b64toBlob(b64Data, "image/png")
formData = new FormData()
formData.append("fileName", blob)