Отправить объект Blob с формой POST - PullRequest
0 голосов
/ 03 мая 2018

Я записываю звук с микрофона, и мне нужно отправить его на сервер с формой POST.

Я могу записать и получить объект BLOB-объекта, но я не знаю, как отправить.
Я попытался преобразовать BLOB-объект в ArrayBuffer и установить скрытое поле со значением, но я не уверен, что это правильный путь.

Это код js для получения BLOB-объекта, преобразования в ArrayBuffer и установки в скрытое поле:

var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function(event) {
    arrayBuffer = event.target.result;

    jQuery('hidden_field').val(arrayBuffer);
};
fileReader.readAsArrayBuffer(blobObject);

После этого я просто отправляю форму обычным способом с помощью кнопки отправки.
На сервере, если я выполняю команду dd для объекта запроса, это то, что я получаю:

array:2 [▼
    "_token" => "8HcKsoGblW9lEPVY0JYrFDbDAajdb63xdSQC3r5E"
    "hidden_field" => "[object ArrayBuffer]"
]

Я не знаю, правильно это или нет.
Если это правильно, как я могу справиться с этим?

ОБНОВЛЕНО
Я решил отправить BLOB-объект в скрытое поле в виде строки base64 с помощью следующего кода:

var fileReader = new FileReader();
fileReader.onload = function(event) {
     jQuery('#hidden').val(fileReader.result.substr(fileReader.result.indexOf(',')+1));
};
fileReader.readAsDataURL(s);

1 Ответ

0 голосов
/ 04 мая 2018

Вы можете прочитать его как dataURI и назначить hidden_field строкой base64, а затем декодировать его на бэкэнде ...

в противном случае это единственный способ добавить блоб к форме

// only way to change input[type=file] value is with a other FileList instance
// and this is currently the only way to construct a new FileList
function createFileList(a) {
  a = [].slice.call(Array.isArray(a) ? a : arguments)
  for (var c, b = c = a.length, d = !0; b-- && d;) d = a[b] instanceof File
  if (!d) throw new TypeError('expected argument to FileList is File or array of File objects')
  for (b = (new ClipboardEvent('')).clipboardData || new DataTransfer; c--;) b.items.add(a[c])
  return b.files
}

var file = new File([blobObject], 'filename.txt', {type: 'text/plain'})
var input = document.createElement('input')

input.type = 'file'
// input.multiple = true
input.files = createFileList(file)
input.name = 'hidden_field'
input.hidden = true

form.appendChild(input)

это не будет работать в каждом браузере, так как у всех есть ограничения, я точно знаю, что Firefox и Blink поддерживают, это не проверялось в других браузерах

другое решение - сделать запрос с помощью ajax + FormData

var form = document.querySelector('form')

// get all other field in the form
var fd = new FormData(form)
// or start of with a empty form
var fd = new FormData()

// append the needed blob to the formdata
fd.append('hidden_field', blobObject, 'filename.txt')

fetch(form.action, {
  method: form.method,
  body: fd
}).then(function(res) {
  if (!res.ok) {
    console.log('something unexpected happened')
  }
  res.text().then(function(text) {
    // navigate to forms action page
    // location.href = form.action
  })
})

это больше кросс-браузерная поддержка

...