javascript如何上传blob?

Yan*_*ang 95 javascript jquery html5

我在这个结构中有一个blob数据:

Blob {type: "audio/wav", size: 655404, slice: function}
size: 655404
type: "audio/wav"
__proto__: Blob
Run Code Online (Sandbox Code Playgroud)

它实际上是使用最近的Chrome getUerMedia()Recorder.js记录的声音数据

如何使用jquery的post方法将此blob上传到服务器?我没试过就试过这个:

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

Fab*_*tté 109

试试这个

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);
});
Run Code Online (Sandbox Code Playgroud)

您需要使用FormData API并设置jQuery.ajax's processDatacontentTypeto false.

  • 安全要求阻止编程设置文件输入值:http://stackoverflow.com/questions/1696877/how-to-set-a-value-to-a-file-input-in-html (11认同)
  • 请注意,与文件不同,Blob在发送到服务器时具有通用文件名.但是你可以在FormData中描述Blob文件名:http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name (9认同)
  • 你知道如何在没有 AJAX 的情况下做到这一点吗? (3认同)
  • 基本上要做`$('input [type = file]')。value = blob` (3认同)

cha*_*oir 37

2019年更新

这会使用最新的Fetch API更新答案,并且不需要 jQuery。

免责声明:不适用于 IE、Opera Mini 和旧浏览器。参见caniuse

基本获取

它可以很简单:

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

带错误处理的获取

添加错误处理后,它可能如下所示:

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);
            });
Run Code Online (Sandbox Code Playgroud)

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);
?>
Run Code Online (Sandbox Code Playgroud)


yee*_*ing 17

我无法使用上面的示例来处理blob,我想知道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 script
            console.log(data);
        });
    };      
    // trigger the read from the reader...
    reader.readAsDataURL(blob);

}
Run Code Online (Sandbox Code Playgroud)

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);
?>
Run Code Online (Sandbox Code Playgroud)


Dmi*_*ich 16

实际上,您不必使用从JavaScript FormData发送Blob到服务器(File也是a 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
});
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

当然,如果要使用"AJAX"实现替换传统的HTML多部分表单(即,后端使用多部分表单数据),则需要使用FormData另一个答案中描述的对象.

来源:XMLHttpRequest2中的新技巧| HTML5 Rocks


Sou*_*sak 11

我能够通过不使用FormData但使用javascript对象来传输blob来获得@yeeking示例.使用使用recorder.js创建的声音blob.在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);
}
Run Code Online (Sandbox Code Playgroud)

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);
?>
Run Code Online (Sandbox Code Playgroud)

  • 小心php文件 - 如果允许HTTP客户端设置文件名,他们可以使用它将恶意内容上传到他们选择的文件和目录中.(只要Apache可以在那里写) (6认同)