Конвертировать и объект в файл и отправить через Ajax - PullRequest
0 голосов
/ 19 марта 2019

Этот и этот ответ - моя мотивация для попытки преобразовать тип object в file и добавить FormData следующим образом:

  var fileBag = new FormData(); 
  fileArray.forEach(function(element) {        
        file_name = element.name;
        file_type = element.type;       
        var file = new File([element], file_name, {type:file_type}); 
        console.log("file type= ", typeof file);    // o/p is object
        fileBag.append(file_name, file);
  });

Когда я попробовал то же самое, typeof вновь созданный файл является объектом (я ожидаю, что это будет файл) после преобразования в файл. File Объект до и после преобразования такой же, как и так:

File
lastModified: 1543472205025
lastModifiedDate: Thu Nov 29 2018 11:46:45 GMT+0530 (India Standard Time) {}
name: "testFile.xlsx"
size: 1119910
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
webkitRelativePath: ""
__proto__: File

Вот так я отправляю через Ajax

$.ajax({
    url: '/project/url/', 
    type: 'POST',    
    data: {'file': fileBag},
    enctype: 'multipart/form-data',
    processData: false,
    contentType: false,
    dataType: "json",
    success: function (data) { 
        console.log("data= ",data);

    },
    error: (error) => {
        console.log(JSON.stringify(error));
    }

}); 

Я пробовал это как в Django, так и в PHP. Я получаю пустые массивы. Мой вопрос:

1) Будет ли typeof до и после преобразования одинаковым?

2) Как я могу отправить массивы файловых объектов в бэкэнд? Есть ли другое решение?

Вот мой кодекс того же.

Редактировать: Кодовый код

var fileArray = [];
var fileBag = new FormData();

function handleFileUpload(event)
{
  var fileUploadButtonId = event.currentTarget.id;
  var files = document.getElementById(fileUploadButtonId).files;
  var fileBag = new FormData(); 
  var arrayOfAllUploadedFiles = Array.from(files);

  for(var i=0; i<arrayOfAllUploadedFiles.length; i++)
  {
    fileArray.push(arrayOfAllUploadedFiles[i]);
  }


  fileArray.forEach(function(element) {        
        file_name = element.name;
        file_type = element.type;       
        var file = new File([element], file_name, {type:file_type}); 
        console.log("file type= ", typeof file);    // o/p is object.  // o/p is object. Shouldn't this be 'file'?
        fileBag.append(file_name, file);
        alert("filebag= ",fileBag);  // this is empty
  });
}

1 Ответ

1 голос
/ 19 марта 2019

Будет ли typeof до и после преобразования одинаковым?

Поскольку "file" не является типом данных JavaScript.Все, что не является примитивом, является объектом.

console.log(typeof 1);
console.log(typeof "1");
console.log(typeof null);
console.log(typeof undefined);
console.log(typeof [1,2,3]);
console.log(typeof {hello: "world"});
console.log(typeof new Date());
console.log(typeof document.body);
console.log(typeof window);

2) Как я могу отправить массивы файловых объектов в бэкэнд?Есть ли другое решение?

  1. Понимание того, как данные форматируются при отправке их по HTTP
  2. Понимание ограничений jQuery

Youне могу отправить массив.Вы можете отправить только некоторый текст, который серверный код может собрать в массив.

Для обоих стандартных кодировок, поддерживаемых формами , PHP заполнит $_POST данными в них.

Если имя поля в этих данных заканчивается на [], PHP поместит массив в $_POST.

Если вы передадите массив в jQuery ajax:

data: { someValue: [1, 2, 3] }

Тогда jQuery закодирует его как:

someValue[]=1&someValue[]=2&someValue[]=3

… поэтому PHP сгенерирует массив.

Однако значения должны быть такими, которые понимает jQuery.Он не может обрабатывать FormData объекты.

Если вы хотите отправить объект FormData (что необходимо сделать для отправки файлов), вам нужно отправить его вместо объекта:

jQuery.ajax({
    url: "/foo",
    data: a_form_data_object,
    processData: false,
    contentType: false,
});

Вам нужно processData, чтобы он не пытался преобразовать объект FormData (т. е. он позволит XMLHttpRequest делать это).Вам нужно contentType, чтобы остановить его, переопределяя один XMLHttpRequest, сгенерированный из объекта FormData.

Итак, чтобы отправить массив, мы вернемся к правилам, которые я описал выше.Вы сказали:

fileBag.append(file_name, file);

Но чтобы получить массив, вам нужно имя, заканчивающееся на [].

fileBag.append("myname[]", file);

Наконец, не видно вваш вопрос, но, глядя на ваш кодекс.Это даст вам набор файлов:

document.getElementById(fileUploadButtonId).files;

Поскольку они являются файлами, использование кода для их преобразования в файлов не даетСмысл.

Вы можете упростить свой код:

var fileBag = new FormData(); 
var files = document.getElementById(fileUploadButtonId).files;
var arrayOfAllUploadedFiles = Array.from(files);
fileArray.forEach(file => fileBag.append("myname[]", file);
jQuery.ajax({
    url: "/foo",
    data: fileBag,
    processData: false,
    contentType: false,
});
...