【发布时间】:2012-04-14 15:26:56
【问题描述】:
我正在使用新的 FormData 接口在 Javascript 中发布文件。当我使用 Safari 5.1.5 使用“multipart/form-data”发送文件时,Safari 将文件强制转换为字符串,而不是发送实际文件内容,而是发送 [object Object]。
例子:
var formdata = new FormData();
formdata.append("file", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://example.com/upload", true);
xhr.send(formdata);
Safari 最终发送的内容:
Origin: https://example.com/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarycLc5AIMWzGxu58n8
Referer: https://example.com/upload
------WebKitFormBoundarycLc5AIMWzGxu58n8
Content-Disposition: form-data; name="file"
[object Object]
我的文件因此被上传,但文件的内容,你猜对了,[object Object]。
这里到底发生了什么?这是 Safari 的错误吗?
编辑 1
对于那些好奇如何动态生成 JS Blob 的人,这里有一个例子:
var Builder = (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder);
var builder = new Builder();
builder.append("hello, world");
var file = builder.getBlob("text/plain")
不幸的是,这不在 Safari 上工作,所以将它包含在问题中并没有真正帮助。
编辑 2
我引用的文件对象来自对 DOM 元素的拖放操作。这是如何检索文件的示例。在 DOM 加载后运行以下命令。
function cancel(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
if (e.preventDefault) {
e.preventDefault();
}
}
function drop(e) {
cancel(e);
for (var i=0; i<e.dataTransfer.files.length; i++) {
file = e.dataTransfer.files[i];
}
}
var elem = document.getElementById("upload-area");
elem.addEventListener("drop", drop, false);
【问题讨论】:
-
需要在第 2 行查看定义
file变量的代码。 -
file由拖放操作提供。它不是动态创建的。在其他浏览器中,您可以动态构建Blob,但 Safari 还不能这样做。 -
问题已更新,代码解释了我如何获得
file对象。 -
只需将这个确切的代码放在我服务器上一个快速而肮脏的页面上,它似乎可以正常工作。它只是将帖子发布到一个 PHP 文件,该文件将上传内容放入一个临时目录,然后读取其内容并将其回显。 kevincennis.com/uploadtest.
-
哇——它确实有效。情节变厚了。这一定与我忽略的问题有关(我认为它不相关......我认为它现在是)。我通过 postMessage 将文件发送到接收 drop 的页面内的 iframe。 iframe 包含在收到 postMessage 之前进行侦听、创建
FormData,然后发布到 URL 的脚本。
标签: javascript safari uploading