如何为作为 FormData 上传的 Blob 提供文件名?
Posted
技术标签:
【中文标题】如何为作为 FormData 上传的 Blob 提供文件名?【英文标题】:How to give a Blob uploaded as FormData a file name? 【发布时间】: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
有没有办法在客户端设置或接收这个文件名,而不进行任何服务器端通信?
【问题讨论】:
【参考方案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);
【讨论】:
问题是您从剪贴板获取文件/blob。你所描述的与这个问题有关:***.com/questions/27251953/… 在 IE 上不起作用,因为它仍然不支持 File 构造函数。 @Mahib MDN's documentation on theFile
constructor 表明它受 IE10 及更高版本的支持。
@RobertK.Bell,我实际上检查了 Edge,但它不起作用:(,然后我不得不改回 blob 构造函数。
@Mahib 你是对的 ― issue #9551546 on Edge's tracker File
构造函数抛出 Function Expected
异常【参考方案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:originGUID
,在 Firefox 中将被格式化为 moz-filedata:GUID
。源是协议的协议+主机+非标准端口。例如,blob:http://***.com/e7bc644d-d174-4d5e-b85d-beeb89c17743
或 blob: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,但它是相关的。
【讨论】:
以上是关于如何为作为 FormData 上传的 Blob 提供文件名?的主要内容,如果未能解决你的问题,请参考以下文章