Как javascript может загружать blob?
У меня есть данные blob в этой структуре:
Blob {type: "audio/wav", size: 655404, slice: function}
size: 655404
type: "audio/wav"
__proto__: Blob
Это действительно звуковые данные, записанные с использованием последних getUerMedia()
и Recorder.js
Как я могу загрузить этот blob на сервер, используя метод jquery post? Я пробовал это без везения:
$.post('http://localhost/upload.php', { fname: "test.wav", data: soundBlob },
function(responseText) {
console.log(responseText);
});
Ответы
Ответ 1
Попробуйте это
var fd = new FormData();
fd.append('fname', 'test.wav');
fd.append('data', soundBlob);
$.ajax({
type: 'POST',
url: '/upload.php',
data: fd,
processData: false,
contentType: false
}).done(function(data) {
console.log(data);
});
Вам необходимо использовать FormData API и установить jQuery.ajax
processData
и contentType
на false
.
Ответ 2
Я не мог заставить приведенный выше пример работать с blobs, и я хотел знать, что именно находится в upload.php. Итак, вы идете:
(тестируется только в Chrome 28.0.1500.95)
// javascript function that uploads a blob to upload.php
function uploadBlob(){
// create a blob here for testing
var blob = new Blob(["i am a blob"]);
//var blob = yourAudioBlobCapturedFromWebAudioAPI;// for example
var reader = new FileReader();
// this function is triggered once a call to readAsDataURL returns
reader.onload = function(event){
var fd = new FormData();
fd.append('fname', 'test.txt');
fd.append('data', event.target.result);
$.ajax({
type: 'POST',
url: 'upload.php',
data: fd,
processData: false,
contentType: false
}).done(function(data) {
// print the output from the upload.PHP скрипт
console.log(data);
});
};
// trigger the read from the reader...
reader.readAsDataURL(blob);
}
Содержимое upload.php:
<?
// pull the raw binary data from the POST array
$data = substr($_POST['data'], strpos($_POST['data'], ",") + 1);
// decode it
$decodedData = base64_decode($data);
// print out the raw data,
echo ($decodedData);
$filename = "test.txt";
// write the data out to the file
$fp = fopen($filename, 'wb');
fwrite($fp, $decodedData);
fclose($fp);
?>
Ответ 3
Фактически вам не нужно использовать FormData
для отправки Blob
на сервер из JavaScript (а File
также является Blob
).
Пример jQuery:
var file = $('#fileInput').get(0).files.item(0); // instance of File
$.ajax({
type: 'POST',
url: 'upload.php',
data: file,
contentType: 'application/my-binary-type', // set accordingly
processData: false
});
Пример ванильного JavaScript:
var file = $('#fileInput').get(0).files.item(0); // instance of File
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload.php', true);
xhr.onload = function(e) { ... };
xhr.send(file);
Предположим, что если вы заменяете традиционную многостраничную форму HTML с помощью реализации "AJAX" (т.е. ваш сервер использует многостраничные данные формы), вы хотите использовать объект FormData
, как описано в другом ответе.
Источник: Новые трюки в XMLHttpRequest2 | Скалы HTML5
Ответ 4
Я смог получить пример @yeeking для работы, не используя FormData, но используя объект javascript для переноса blob. Работает со звуковым блобом, созданным с использованием recorder.js. Протестировано в Chrome версии 32.0.1700.107
function uploadAudio( blob ) {
var reader = new FileReader();
reader.onload = function(event){
var fd = {};
fd["fname"] = "test.wav";
fd["data"] = event.target.result;
$.ajax({
type: 'POST',
url: 'upload.php',
data: fd,
dataType: 'text'
}).done(function(data) {
console.log(data);
});
};
reader.readAsDataURL(blob);
}
Содержимое upload.php
<?
// pull the raw binary data from the POST array
$data = substr($_POST['data'], strpos($_POST['data'], ",") + 1);
// decode it
$decodedData = base64_decode($data);
// print out the raw data,
$filename = $_POST['fname'];
echo $filename;
// write the data out to the file
$fp = fopen($filename, 'wb');
fwrite($fp, $decodedData);
fclose($fp);
?>
Ответ 5
Я перепробовал все решения, приведенные выше, и, кроме того, ответы на них. Решения, включающие, но не ограничиваясь, передачу большого двоичного объекта вручную в свойство файла HTMLInputElement, вызов всех методов readAs * в FileReader, использование экземпляра File в качестве второго аргумента для вызова FormData.append, попытку получения данных большого двоичного объекта в виде строки путем получения значения в URL.createObjectURL(myBlob), которые оказались неприятными и сломали мою машину.
Теперь, если вы попытаетесь сделать это или даже больше и все равно обнаружите, что не можете загрузить свой BLOB-объект, это может означать, что проблема на стороне сервера. В моем случае мой BLOB-объект превысил ограничение http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize и post_max_size в PHP.INI, поэтому файл покинул интерфейс форма, но отклоняется сервером. Вы можете увеличить это значение непосредственно в PHP.INI или через .htaccess.
Ответ 6
2019 Обновление
Это обновляет ответы с использованием новейшего API Fetch и не требует jQuery.
Отказ от ответственности: не работает в IE, Opera Mini и старых браузерах. Смотри caniuse.
Основная выборка
Это может быть так просто, как:
fetch('https://example.com/upload.php', {method:"POST", body:blobData})
.then(response => console.log(response.text()))
Получить с обработкой ошибок
После добавления обработки ошибок это может выглядеть так:
fetch('https://example.com/upload.php', {method:"POST", body:blobData})
.then(response => {
if (response.ok) return response;
else throw Error('Server returned ${response.status}: ${response.statusText}')
})
.then(response => console.log(response.text()))
.catch(err => {
alert(err);
});
PHP код
Это серверный код в upload.php.
<?php
// gets entire POST body
$data = file_get_contents('php://input');
// write the data out to the file
$fp = fopen("path/to/file", "wb");
fwrite($fp, $data);
fclose($fp);
?>