我对File API以及使用JavaScript上传文件以及如何执行此操作有疑问。
我已经使用了一个非常简单的文件上传器,它只是从输入中获取文件并向服务器发出请求,然后服务器处理文件并在服务器上传上传目录中的副本文件。
但是,我试图让人们在上传之前预览文件。所以我利用了File API,特别是new FileReader()
和以下readAsDataURL()
。
文件对象有一个属性列表,例如.size
和.lastModifiedDate
,我将readAsDataURL()
输出添加到我的文件对象作为属性,以便在我的Angular {{1}中轻松访问}}
我的问题是,我这样做是因为我这样做可以将dataurl存储在数据库中而不是上传实际的文件?我不确定是否直接使用它的dataurl修改文件数据作为属性会影响其传输。
最佳做法是什么?上传文件是否更好,或者你只是存储dataurl然后输出,因为这本质上就是文件本身?我不应该直接修改文件对象吗?
谢谢。
编辑:我还应该注意,这是一个客户的项目,希望用户很难从应用程序中获取上传的内容并保存,然后再重新发布。保存文件是否是数据库中的URL会减少右键单击保存行为或不是真的吗?
答案 0 :(得分:1)
预览文件有多种方法。首先是你提到的带文件阅读器的dataURL。但也有URL.createObjectURL更快
对base64进行解码和编码需要更长的时间,它需要更多的计算,如果是二进制格式则需要更多的CPU /内存。
我可以在下面演示
var url = 'https://upload.wikimedia.org/wikipedia/commons/c/cc/ESC_large_ISS022_ISS022-E-11387-edit_01.JPG'
fetch(url).then(res => res.blob()).then(blob => {
// Simulates a file as if you where to upload it throght a file input and listen for on change
var files = [blob]
var img = new Image
var t = performance.now()
var fr = new FileReader
img.onload = () => {
// show it...
// $('body').append(img)
var ms = performance.now() - t
document.body.innerHTML = `it took ${ms.toFixed(0)}ms to load the image with FileReader<br>`
// Now create a Object url instead of using base64 that takes time to
// 1 encode blob to base64
// 2 decode it back again from base64 to binary
var t2 = performance.now()
var img2 = new Image
img2.onload = () => {
// show it...
// $('body').append(img)
var ms2 = performance.now() - t2
document.body.innerHTML += `it took ${ms2.toFixed(0)}ms to load the image with URL.createObjectURL<br><br>`
document.body.innerHTML += `URL.createObjectURL was ${(ms - ms2).toFixed(0)}ms faster`
}
img2.src = URL.createObjectURL(files[0])
}
fr.onload = () => (img.src = fr.result)
fr.readAsDataURL(files[0])
})
base64将大约3倍。对于移动设备,我认为您希望节省带宽和电池。
但是还有延迟做一个额外的请求,但这就是http 2来救援的地方