我使用新的FormData接口在
Javascript中发布文件.当我使用“multipart / form-data”使用Safari 5.1.5发送文件时,Safari会将File强制转换为字符串,而不是发送实际文件内容,而是发送[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 bug吗?
编辑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);
最佳答案 当我提出这个问题时,这似乎并不重要,但我想出了这个问题.在使用XMLHttopRequest上传文件之前,我调用了jQuery的$.ajax方法来调用后端中的端点来准备文件.
简而言之:这是Safari上的jQuery中的一个错误.我使用for循环来处理文件列表,然后上传它们.我将一个文件对象作为参数传递给jQuery $.ajax方法,以便在执行多个循环时不会重写我想要的文件对象.例如.
for (i in files) {
var file = files[i];
$.ajax({
method: "POST",
myFile: file,
success: function(response) {
var file = this.myFile;
// ...
});
}
事实证明,jQuery碰巧在Safari中错误地克隆了文件对象.因此,当设置为this.myFile时,它不会将其转换为文件,而是将其转换为对象,从而使其失去所有特殊的“类文件”功能.其他浏览器似乎都明白,尽管如此,该对象仍然是一个文件.
答案是编写一个回调方法来处理文件上传.
function handleFile(file) {
$.ajax({
method: "POST",
success: function(response) {
// ...
});
}
for (var i in files) {
handleFile(files[i]);
}
附:要将此文件提交给jQuery错误跟踪器,但只是想保留它,以防其他人有同样的问题.