Safari преобразует файл в [объект объекта] при вставке в FormData.Как исправить? - PullRequest
4 голосов
/ 31 марта 2012

Я публикую файл в Javascript, используя новый интерфейс FormData.Когда я отправляю файл с использованием 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 ]

2 голосов
/ 06 апреля 2012

Это не имело значения, когда я задавал вопрос, но я понял это.Перед загрузкой файла с использованием XMLHttopRequest я вызвал метод jQuery $.ajax, чтобы вызвать конечную точку в нашем бэкэнде для подготовки файла.

Вкратце: это ошибка в jQuery в Safari.Я использовал цикл for для обработки списка файлов и загрузки их.Я передал файловый объект в качестве параметра методу jQuery $.ajax, чтобы нужный мне файловый объект не был переписан при выполнении нескольких циклов.Например,

for (i in files) {
    var file = files[i];
    $.ajax({
        method: "POST",
        myFile: file,
        success: function(response) {
            var file = this.myFile;
            // ...
    });
}

Оказывается, что jQuery неправильно клонирует объект file в Safari.Таким образом, вместо приведения его к файлу, когда установлено значение this.myFile, он преобразует его в объект, таким образом, он теряет все свои специальные «файловые» возможности.Другие браузеры, похоже, понимают, что объект по-прежнему является файлом, несмотря на это.

Ответ заключается в написании метода обратного вызова для обработки загрузки файла.

function handleFile(file) {
    $.ajax({
        method: "POST",
        success: function(response) {
            // ...
    });
}

for (var i in files) {
    handleFile(files[i]);
}

PS.в трекер ошибок jQuery, но просто хотел сохранить это здесь на случай, если у кого-то еще возникнет такая же проблема.

0 голосов
/ 31 марта 2012

file должно быть String, в противном случае, если это Object, его метод toString() вызывается при добавлении его к объекту данных формы.

Это напрямую связано с Blob, не работающим в Safari. Для того, чтобы это работало в Safari, вам понадобится способ принудительно заставить файл String, что, очевидно, не самая простая вещь (даже не знаю, возможно ли это по соображениям безопасности?).

...