Публикация данных файла в кодировке URL с помощью Ajax

Можно ли сделать это? Более подробно:

  1. У меня есть файловый объект, который я получил из элемента ввода
  2. Я хочу загрузить это на сервер вместе с парой пар ключ/значение со связанными данными (имя файла и т.д.)
  3. Я хочу сделать это с помощью Ajax, потому что все остальное в системе использует Ajax, и я стандартизировал обработку успеха/неудачи на основе ответа сервера.
  4. Я хочу сделать это с кодировкой URL, потому что файл маленький, а сервер не реализует multipart/form-data

Я пробовал несколько разных вещей, но ни одна из них не была совершенно правильной. Этот код отправляет данные файла «как есть» (т. е. фактически необработанный двоичный файл, а не как пару ключ-значение в кодировке URL):

   var files = document.getElementById('idUploadBrowseInput').files;
   var fdata = files[0];
   var jqxhr = $.ajax({
      type        : "POST",
      url         : "/cgi-bin/upload_cgi",
      timeout     : 20000,
      processData : false,
      data        : fdata
   }).always(...etc)

Необработанный двоичный файл был бы в порядке, но мне также нужны другие пары ключ-значение, и, похоже, невозможно отправить их одновременно.

Если я изменю строку data : fdata на data : {fdata : fdata}, тогда данные POST просто станут [object Object] (на FF). Если я удалю processData:false, я получу исключение в jQuery.

API FileReader имеет несколько методов readAs, которые, я думаю, мне следует использовать - предположительно, если я прочитаю содержимое файла в var, тогда я могу просто отправить переменную как часть объекта данных, и все это должно просто работать. Однако это многословно, и я просто хочу сначала убедиться, что нет более прямого способа сделать это.

Обратите внимание, что это сообщение не отвечает вопрос.


person EML    schedule 18.04.2014    source источник
comment
Не уверен, пожалуйста, уточните требование? Спасибо   -  person guest271314    schedule 19.04.2014
comment
Короче говоря, при использовании Ajax вы можете отправить закодированный URL-адрес файла «объект» в виде пары «ключ-значение» вместе с другими парами «ключ-значение»?   -  person EML    schedule 19.04.2014
comment
Если есть возможность, можете выложить cgi штук? Пожалуйста, уточните object ? Пробовали file object как base64 строку? или encodeURIComponent(file) ? Попробуйте Blob и FileReder ? См. developer.mozilla.org/en-US/docs/Web/API. /Blob developer.mozilla.org/en-US/ docs/Web/API/File stackoverflow.com/questions/23140007/   -  person guest271314    schedule 19.04.2014


Ответы (1)


Мне удалось отправить файл с помощью AJAX (и jQuery), есть даже два разных способа сделать это:

const fileInput = document.getElementById('file-upload'); // refers to <input type="file">
const file = fileInput.files[0];

let reader = new FileReader();

reader.onload = function () {
  console.log(reader.result);

  $.ajax({
    type: 'POST',
    url: '/file-upload',

    // data: { file: reader.result }, // #1

    // data: reader.result,           // #2
    // processData: false,

    success: function (response) {
      alert(response);
    }
  });
}

// reader.readAsBinaryString(file); // #1
// reader.readAsArrayBuffer(file);  // #2

Первый метод отправляет версию файла в кодировке URL. На стороне сервера это выглядит так:

POST /file-upload HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Content-Length: 59577
Accept: */*
Origin: http://127.0.0.1:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 OPR/56.0.3051.116
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://127.0.0.1:8080/test
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US;q=0.8,en;q=0.7

file=%00%00%00%02%00%00%00%C3%89%5B%C3%B1%15Y%2B%C3%86%C2%82%04%5C%0A%C2%...

Второй метод отправляет файл в необработанном виде — весь контент представляет собой чистые двоичные данные:

POST /file-upload HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Content-Length: 12342
Accept: */*
Origin: http://127.0.0.1:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 OPR/56.0.3051.116
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://127.0.0.1:8080/test
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US;q=0.8,en;q=0.7

É[ñY+Æ\»H*|ṲFÝ▒§®Y3NÙ+2¤"ã0èT...

Обратите внимание на поле Content-Length — необработанная форма определенно более оптимальна, но она не позволяет вам удобно отправлять любые другие данные пары ключ-значение, такие как первая форма.

person Xeverous    schedule 21.12.2018