【问题标题】:How to give a Blob uploaded as FormData a file name?如何为作为 FormData 上传的 Blob 提供文件名?
【发布时间】:2011-10-03 15:29:00
【问题描述】:

我目前正在使用以下代码上传从剪贴板粘贴的图像:

// Turns out getAsFile will return a blob, not a file
var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();
form.append("blob",blob);
request.open(
            "POST",
            "/upload",
            true
        );
request.send(form);

原来上传的表单字段接收名称类似于:Blob157fce71535b4f93ba92ac6053d81e3a

有没有办法在客户端设置或接收这个文件名,而不进行任何服务器端通信?

【问题讨论】:

    标签: javascript dom google-chrome form-data


    【解决方案1】:

    对于 Chrome、Safari 和 Firefox,只需使用这个:

    form.append("blob", blob, filename);
    

    (见MDN documentation

    【讨论】:

    • 你从哪里注意到这个???这很棒!有没有关于 chrome 版本对此支持的链接?
    • 顺便说一句,这在规范中:w3.org/TR/XMLHttpRequest2/#interface-formdata
    • 另外,我正在研究 firefox 错误来修复这个问题,我已经修复了它,但我有一些“样式问题”bugzilla.mozilla.org/show_bug.cgi?id=690659(我目前没有时间修复这个问题补丁,所以如果有人想拿起它,我会非常满意)
    • @Chiguireitor 还没有修复?
    • 这是来自 MDN 的“兼容性表”。请注意,在这篇文章中,附加文件名在除 Chrome 和 FF 之外的所有浏览器上都有不稳定的支持:developer.mozilla.org/en-US/docs/Web/API/…
    【解决方案2】:

    在此处添加,因为它似乎不在此处。

    除了 form.append("blob",blob, filename); 的出色解决方案之外,您还可以将 blob 转换为 File 实例:

    var blob = new Blob([JSON.stringify([0,1,2])], {type : 'application/json'});
    var fileOfBlob = new File([blob], 'aFileName.json');
    form.append("upload", fileOfBlob);
    

    【讨论】:

    【解决方案3】:

    由于您将数据粘贴到剪贴板,因此没有可靠的方法来了解文件的来源及其属性(包括名称)。

    最好的办法是提出自己的文件命名方案并与 blob 一起发送。

    form.append("filename",getFileName());
    form.append("blob",blob);
    
    function getFileName() {
     // logic to generate file names
    }
    

    【讨论】:

    • 问题不要求原始文件名。这个答案完全偏离目标。
    • @NielsAbildgaard:真的吗?它询问分配文件名,原始文件名不符合有效文件名吗?
    • 答案没有回答原始问题(除了“这里有一个替代方案”),而是为没有被问到的问题提供了答案,坦率地说,是题外话。
    【解决方案4】:

    该名称看起来是从对象 URL GUID 派生的。执行以下操作以获取名称派生自的对象 URL。

    var URL = self.URL || self.webkitURL || self;
    var object_url = URL.createObjectURL(blob);
    URL.revokeObjectURL(object_url);
    

    object_url 在 Google Chrome 中将被格式化为 blob:{origin}{GUID},在 Firefox 中将被格式化为 moz-filedata:{GUID}。源是协议的协议+主机+非标准端口。例如,blob:http://stackoverflow.com/e7bc644d-d174-4d5e-b85d-beeb89c17743blob:http://[::1]:123/15111656-e46c-411d-a697-a09d23ec9a99。您可能想要提取 GUID 并去除任何破折号。

    【讨论】:

      【解决方案5】:

      尚未对其进行测试,但这应该会提醒 blobs 数据 url:

      var blob = event.clipboardData.items[0].getAsFile(), 
          form = new FormData(),
          request = new XMLHttpRequest();
      
      var reader = new FileReader();
      reader.onload = function(event) {
        alert(event.target.result); // <-- data url
      };
      reader.readAsDataURL(blob);
      

      【讨论】:

      • 这将提醒 blob 作为数据 url。我想要接收/设置的是在进行表单发布上传时附加到表单字段的文件名。
      • 那我不知道没有服务器端通信的办法。
      【解决方案6】:

      这实际上取决于另一端的服务器是如何配置的,以及它如何处理 blob 帖子的模块。您可以尝试将所需的名称放在帖子的路径中。

      request.open(
          "POST",
          "/upload/myname.bmp",
          true
      );
      

      【讨论】:

        【解决方案7】:

        您使用的是 Google App Engine 吗? 您可以使用 cookie(由 JavaScript 制作)来维护文件名和从服务器接收到的名称之间的关系。

        【讨论】:

          【解决方案8】:

          当您使用 Google Chrome 时,您可以为此使用/滥用Google Filesystem API。在这里,您可以创建具有指定名称的文件并将 blob 的内容写入其中。然后就可以将结果返回给用户了。

          我还没有找到 Firefox 的好方法;可能需要一小块像 downloadify 这样的 Flash 来命名 blob。

          IE10 在BlobBuilder 中有一个msSaveBlob() 函数。

          也许这更多地用于下载 blob,但它是相关的。

          【讨论】:

            猜你喜欢
            • 2013-12-04
            • 1970-01-01
            • 2022-01-06
            • 2012-01-19
            • 1970-01-01
            • 2018-04-24
            • 2013-12-25
            • 2013-08-17
            • 2017-05-14
            相关资源
            最近更新 更多