【问题标题】:File Uploading ReadAsDataUrl文件上传 ReadAsDataUrl
【发布时间】:2017-11-20 09:14:58
【问题描述】:

我有一个关于File API 和用 JavaScript 上传文件以及我应该如何做到这一点的问题。

我已经使用了一个非常简单的文件上传器,它只是从输入中获取文件并向服务器发出请求,然后服务器处理文件并将副本文件上传到服务器上的上传目录中。

但是,我试图让人们选择在上传文件之前预览文件。所以我利用了 File API,特别是 new FileReader() 和下面的 readAsDataURL()

文件对象有一个属性列表,例如.size.lastModifiedDate,我将readAsDataURL() 输出作为属性添加到我的文件对象中,以便在我的Angular ng-repeat() 中轻松访问。

我的问题是,当我这样做时,我想到我可以将 dataurl 存储在数据库中而不是上传实际文件?我不确定直接使用它的 dataurl 作为属性修改文件数据是否会影响其传输。

最佳做法是什么?上传文件更好还是只存储dataurl然后输出它,因为这本质上是文件本身?不应该直接修改文件对象吗?

谢谢。

编辑:我还应该指出,这是一个客户项目,它希望用户很难简单地从应用程序中获取上传的内容并保存并重新分发它。将文件保存为数据库中的 url 是否会减轻右键单击另存为行为?

【问题讨论】:

  • 我认为这取决于您将如何使用图像。存储 url 意味着您确信该 url 始终可以访问,即使在另一台电脑或位置。如果 url 来自其他站点,那么您需要确保该站点永远不会关闭,否则会影响您的产品。根据您的描述,您有人上传内容并让用户查看它,如果文件在本地计算机中,我认为用户将无法访问该文件。至于另存为的情况,只要内容显示在用户的浏览器中,我认为没有什么可以阻止用户复制它。
  • @Surely 我的意思是 dataurl,它与来自另一个域的可访问性无关,因为我理解它是作为字符串输出的文件。
  • 对不起,我误会了。只要你有内容,我认为直接存储内容是没有问题的。您可能会丢失一些其他信息,例如文件名。您的服务器也需要进行一些更改才能将上传的数据转换为文件。

标签: javascript file-upload


【解决方案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 来救援的地方

【讨论】:

    猜你喜欢
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    相关资源
    最近更新 更多