How can javascript upload a blob?

前端 未结 6 2145
旧时难觅i
旧时难觅i 2020-11-22 11:29

I have a blob data in this structure:

Blob {type: \"audio/wav\", size: 655404, slice: function}
size: 655404
type: \"audio/wav\"
__proto__: Blob
相关标签:
6条回答
  • 2020-11-22 11:39

    You actually don't have to use FormData to send a Blob to the server from JavaScript (and a File is also a Blob).

    jQuery example:

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

    Vanilla JavaScript example:

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

    Granted, if you are replacing a traditional HTML multipart form with an "AJAX" implementation (that is, your back-end consumes multipart form data), you want to use the FormData object as described in another answer.

    Source: New Tricks in XMLHttpRequest2 | HTML5 Rocks

    0 讨论(0)
  • 2020-11-22 11:43

    2019 Update

    This updates the answers with the latest Fetch API and doesn't need jQuery.

    Disclaimer: doesn't work on IE, Opera Mini and older browsers. See caniuse.

    Basic Fetch

    It could be as simple as:

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

    Fetch with Error Handling

    After adding error handling, it could look like:

    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 Code

    This is the server-side code in 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);
    ?>
    
    0 讨论(0)
  • 2020-11-22 11:48

    I was able to get @yeeking example to work by not using FormData but using javascript object to transfer the blob. Works with a sound blob created using recorder.js. Tested in 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);
    }
    

    Contents of 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);
    ?>
    
    0 讨论(0)
  • 2020-11-22 11:57

    I tried all the solutions above and in addition, those in related answers as well. Solutions including but not limited to passing the blob manually to a HTMLInputElement's file property, calling all the readAs* methods on FileReader, using a File instance as second argument for a FormData.append call, trying to get the blob data as a string by getting the values at URL.createObjectURL(myBlob) which turned out nasty and crashed my machine.

    Now, if you happen to attempt those or more and still find you're unable to upload your blob, it could mean the problem is server-side. In my case, my blob exceeded the http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize and post_max_size limit in PHP.INI so the file was leaving the front end form but getting rejected by the server. You could either increase this value directly in PHP.INI or via .htaccess

    0 讨论(0)
  • 2020-11-22 11:59

    I could not get the above example to work with blobs and I wanted to know what exactly is in upload.php. So here you go:

    (tested only in 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);
    
    }
    

    The contents of 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);
    ?>
    
    0 讨论(0)
  • 2020-11-22 12:06

    Try this

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

    You need to use the FormData API and set the jQuery.ajax's processData and contentType to false.

    0 讨论(0)
提交回复
热议问题