128 votes

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

J'ai un blob de données 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 en utilisant le récent Chrome getUerMedia() y Recorder.js

Comment puis-je télécharger ce blob sur le serveur en utilisant la méthode post de Jquery ? J'ai essayé sans succès :

   $.post('http://localhost/upload.php', { fname: "test.wav", data: soundBlob }, 
    function(responseText) {
           console.log(responseText);
    });

142voto

Fabrício Matté Points 26309

Vous pouvez utiliser le API FormData .

Si vous utilisez jquery.ajax vous devez définir processData: false y contentType: false .

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

49voto

chatnoir Points 1379

Mise à jour de 2019

Cela met à jour les réponses avec les dernières API de récupération et n'a pas besoin de jQuery.

Avertissement : ne fonctionne pas sur IE, Opera Mini et les navigateurs plus anciens. Voir caniuse .

Récupération de base

Cela pourrait être aussi simple que :

  fetch(`https://example.com/upload.php`, {method:"POST", body:blobData})
                .then(response => console.log(response.text()))

Récupération avec gestion des erreurs

Après avoir ajouté la gestion des erreurs, cela pourrait ressembler à ceci :

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

Code PHP

C'est le code côté serveur dans 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);
?>

22voto

Dmitry Pashkevich Points 4160

En fait, vous n'avez pas besoin d'utiliser FormData pour envoyer un Blob au serveur à partir de JavaScript (et un File est également un Blob ).

Exemple de 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 de Vanilla 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);

En revanche, si vous remplacez un formulaire multipartite HTML traditionnel par une implémentation "AJAX" (c'est-à-dire que votre back-end consomme les données du formulaire multipartite), vous souhaitez utiliser l'option FormData comme décrit dans une autre réponse.

Fuente: Nouvelles astuces dans XMLHttpRequest2 | HTML5 Rocks

18voto

yeeking Points 125

Je n'ai pas réussi à faire fonctionner l'exemple ci-dessus avec des blobs et je voulais savoir ce qui se trouve exactement dans upload.php. Alors voilà :

(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 de 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);
?>

12voto

Soumen Basak Points 251

J'ai réussi à faire fonctionner l'exemple de @yeeking en n'utilisant pas de FormData mais en utilisant un objet javascript pour transférer le blob. Cela fonctionne avec un blob sonore créé à l'aide de recorder.js. Testé dans Chrome version 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 de 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);
?>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X