Comment javascript peut-il Télécharger un blob?

J'ai une donnée blob dans cette structure:

Blob {type: "audio/wav", size: 655404, slice: function}
size: 655404
type: "audio/wav"
__proto__: Blob

Il s'agit en fait de données sonores enregistrées à l'aide des récents enregistreurs Chrome getUerMedia() et .js

Comment puis-je télécharger ce blob sur le serveur en utilisant la méthode post de jquery? J'ai essayé cela sans aucune chance:

   $.post('http://localhost/upload.php', { fname: "test.wav", data: soundBlob }, 
    function(responseText) {
           console.log(responseText);
    });
73
demandé sur Lee Taylor 2012-11-11 21:06:25

5 réponses

Essayez ceci

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);
});

Vous devez utiliser l'API FormData et définir les jQuery.ajax processData et contentType sur false.

90
répondu Fabrício Matté 2012-11-11 17:26:14

Je n'ai pas pu obtenir l'exemple ci-dessus pour travailler avec des blobs et je voulais savoir ce qui est exactement en téléchargement.php. Donc, ici, vous allez:

(testé uniquement dans 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 script
            console.log(data);
        });
    };      
    // trigger the read from the reader...
    reader.readAsDataURL(blob);

}

Le contenu du téléchargement.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);
?>
14
répondu yeeking 2013-08-15 14:24:01

Vous n'avez pas besoin d'utiliser FormData pour envoyer un Blob au serveur à partir de JavaScript (et un File est aussi un Blob).

Exemple 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
});

Exemple JavaScript vanille:

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);

Certes, si vous remplacez un formulaire HTML multipart traditionnel par une implémentation" AJAX " (c'est-à-dire que votre back-end consomme des données de formulaire multipart), vous souhaitez utiliser l'objet FormData comme décrit dans une autre réponse.

Source: Nouvelles astuces dans XMLHttpRequest2 | HTML5 Roches

14
répondu Dmitry Pashkevich 2017-09-27 20:02:18

J'ai pu faire fonctionner l'exemple @ yeeking en n'utilisant pas FormData mais en utilisant l'objet javascript pour transférer le blob. Fonctionne avec un blob sonore créé à l'aide de l'enregistreur.js. Testé dans la version 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);
}

Contenu du téléchargement.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);
?>
11
répondu Soumen Basak 2014-02-13 05:55:04

J'ai essayé toutes les solutions ci-dessus et en plus, celles des réponses connexes. Solutions comprenant, mais sans s'y limiter, la transmission manuelle du blob à la propriété file D'un HTMLInputElement, en appelant toutes les méthodes readAs* sur FileReader, en utilisant une instance de fichier comme deuxième argument pour un FormData.ajouter un appel, en essayant d'obtenir les données blob sous forme de chaîne en obtenant les valeurs à L'URL.createObjectURL (myBlob) qui s'est avéré méchant et a écrasé ma machine.

Maintenant, si vous essayez ces ou plus et trouvez toujours que vous ne pouvez pas télécharger votre blob, cela pourrait signifier que le problème est Côté Serveur. Dans mon cas, mon blob A dépassé le http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize et post_max_size limite en PHP.INI donc le fichier quittait le serveur mais était rejeté par le serveur. Vous pouvez soit augmenter cette valeur directement en PHP.INI ou via .htaccess

0
répondu I Want Answers 2017-10-17 05:37:47