2016-06-05 4 views
1

Я играю с API FormData. Here - это скрипка, которую я использую - я пытаюсь ввести капли в мою форму и отправить через AJAX.Невозможно отправить полезную нагрузку blob в FormData

//ic0 and tc0 are canvases 
//image0 and thumb0 are file inputs 
function ajaxSubmit(){ 
    var fd = new FormData(document.forms[0]); 
    ic0.toBlob(
     function(blob){ 
      fd.set("image0", blob, "image0.jpg"); 
     }, "image/jpeg", 0.7); 
    tc0.toBlob(
     function(blob){ 
      fd.set("thumb0", blob, "thumb0.jpg"); 
     }, "image/jpeg", 0.7); 
    var xhr = new XMLHttpRequest(); 
    xhr.open("POST", "/ajax-upload/", true); 
    xhr.send(fd); 
} 

поведение браузера немного ... странным:

Chrome 50 (в Ubuntu)

не в состоянии сделать это, дает:

Failed blob:https%3A//fiddle.jshell.net/uuid4 to load resource: the server responded with 404 

Но я думал FormData.set() была поддержана сейчас? Кажется, он работает с non-blobs?

Firefox 46 (в Ubuntu)

Не кажется ли работа FormData() объекта не инициализируются с объектом DOM, который уже имеет необходимые файловые входы (прилагаемые нормальные входы размещены однако). FormData.set(), похоже, не работает с файловыми входами и блоками (вы заметите, что thumb0 является нулевым значением в полезной нагрузке, несмотря на то, что он называет fd.set("thumb0", blob, "thumb0.jpg"). Вы можете проверить, что он установлен, выполнив console.log(fd.get("thumb0")) сразу после настройки. Вы также заметите, что полезная нагрузка .. из image0 некорректно исходное изображение, а не изменять размер холста изображения


это неудобно, не будучи в состоянии настроить ваш многочастному FormData с JavaScript Я Javascript нуб - я просто делаю что-то совершенно неправильно здесь, или эти браузеры не поддерживают API FormData? Как я могу отправить image0 и thumb0 правильно в моей скрипке?


Редактировать: Хорошо, собираюсь наполнить это. Я знаю, что есть большие jquery-зависимые библиотеки, такие как blueimp, и я думаю, что они base64 данные, а не передают как входные данные (плюс я хочу избежать jquery). Я только должен поддерживать последние Chrome или Firefox для этого проекта, и я действительно надеюсь, что смогу сохранить код таким же чистым, как API FormData, кажется, что я могу это сделать. Может ли кто-нибудь успешно захватить изображение с холста и вставить его в полезную нагрузку POST в виде файла? Я хочу, чтобы иметь доступ к этому в request.FILES в django.

+0

Я мог бы быть неправильно, но не отправлять файлы объекта на сервер вместо сгустка? fd.set ('image', e.target.files [0] ') для одного файла? Также убедитесь, что форма multipart –

+0

Глядя на запрос '' Заголовки запросов' и ​​'Request Payload', изображения, кажется, отправляются просто отлично. И сервер, похоже, возвращает '404', а не' 400' или что-то еще. – C14L

+0

Не должны ли вы убедиться, что он отправляется на ваш фактический сервер? Сейчас он отправляется в домен jsfiddle. – aross

ответ

3

Я думаю, что одна вещь, которую вам не хватает здесь, - это асинхронный характер javascript.В вашем ajaxSubmit метод -

function ajaxSubmit(){ 
    var fd = new FormData(document.forms[0]); 
    ic0.toBlob(function(blob){ 
     fd.set("image0", blob, "image0.jpg"); 
    }, "image/jpeg", 0.7);    // this call is asynchronous 
    tc0.toBlob(function(blob){ 
     fd.set("thumb0", blob, "thumb0.jpg"); 
    }, "image/jpeg", 0.7);    // this call is also asynchronous 
    /* 
     hence the below code may get executed before 
      fd.set("image0", blob, "image0.jpg"); 
     this statement. which it does. 
     that is why the canvas files are not submitted. 
    */ 
    var xhr = new XMLHttpRequest(); 
    xhr.open("POST", "/ajax-upload/", true); 
    xhr.send(fd); 
} 

Попробуйте синхронизировать код, как этот

function ajaxSubmit(){ 
    var fd = new FormData(document.forms[0]); 
    ic0.toBlob(function(blob){ 
     fd.set("image0", blob, "image0.jpg"); 
     tc0.toBlob(function(blob){ 
     fd.set("thumb0", blob, "thumb0.jpg"); 
     console.log(blob); 
     console.log("Just blobbed thumb0"); 

     var xhr = new XMLHttpRequest(); 
     xhr.open("POST", "fileuploadbackend.jsp", true); 
     //xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     xhr.send(fd); 
     }, "image/jpeg", 0.7); 

    }, "image/jpeg", 0.7); 
} 

также, как jornare предложил вам следует закомментировать строку

URL.revokeObjectURL(img.src); 

, который вызывает ошибку хром. Вызовите его после загрузки изображения.

также у вас есть несколько элементов с одинаковыми идентификаторами,

<input id="image0" name="image0" type="file" /> 
<label for="image0">image0</label> 
<input id="image0" name="thumb0" type="file" /> 

это не создает проблемы в вашем коде, но идентификаторы должны быть разными.

UPDATE

Здесь работает fiddle.

Примечание: измените URL-адрес запроса на соответствующий URL-адрес.

Следуйте этим ссылкам, чтобы узнать больше о асинхронном поведении javascript и о том, как обрабатываются обратные вызовы AJAX.

+0

Спасибо, в этом была проблема. Можете ли вы порекомендовать ссылку, где я могу читать асинхронное выполнение функций? – Escher

+0

@ Escher вы столкнулись с любой другой проблемой? –

+0

Нет, извините за задержку; награды не могут быть присуждены в течение 24 часов с момента их подачи. Я пробовал вчера, но это не позволило мне. – Escher

1

Просматривая свою скрипку, вы очищали данныеURL перед ее загрузкой, и поэтому миниатюры вообще не загружались. (404)

Я сделал обновленную скрипку https://jsfiddle.net/tLqch5x2/3/

function handleFiles(e){ 
    var img = new Image(); 
    img.onload = function(){ 
     var width = 30; 
     var height = img.height * 30/img.width; 
     e.target.ic0.width = width ; 
     e.target.ic0.height = height ; 
     e.target.tc0.width = width/2 ; 
     e.target.tc0.height = height/2; 
     var ctx = e.target.ic0.getContext("2d"); 
     ctx.drawImage(img, 0, 0, width, height); 
     ctx = e.target.tc0.getContext("2d"); 
     ctx.drawImage(img, 0, 0, width/2, height/2); 
     URL.revokeObjectURL(img.src); //clean up memory here instead 
    }; 
    img.src = URL.createObjectURL(e.target.files[0]); 
    //clean up to prevent memory leak 
    //URL.revokeObjectURL(img.src); //too soon 
} 

У него есть еще 404, но теперь от выкладываем к URL, который не существует на jsfiddle.net. Попробуйте в вашей среде.

Обратите внимание, что в html и коде есть также некоторые другие незначительные изменения. (неправильное присвоение имен изображениям и отсутствие необходимости ссылаться на существующую форму при создании новой формы для отправки)

+0

Спасибо, очевидно, я мало знаю об управлении памятью в javascript. 404 в порядке, я просто хотел проверить полезную нагрузку запроса. В этом случае мне не нужно было ссылаться на существующую форму при создании нового для представления, но в проекте, над которым я работаю, имеется еще 20 полей, заполненных из формы, поэтому я использую его для создания новой формы FormData '. – Escher

 Смежные вопросы

  • Нет связанных вопросов^_^