JavaScript nasıl bir blob yükleyebilir?


107

Bu yapıda bir blob verim var:

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

Aslında en son Chrome getUerMedia()ve Recorder.js kullanılarak kaydedilen ses verileridir

Bu blob'u jquery'nin gönderme yöntemini kullanarak sunucuya nasıl yükleyebilirim? Bunu şanssız denedim:

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

1
Bunun için binaryJS kullanmayı düşünebilirsiniz. Veri akışı yapıyorsanız, bu hile yapabilir.
zehirlemek 20

Yanıtlar:


123

Bunu dene

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'yi kullanmanız ve jQuery.ajax's processDatave ' yi ayarlamanız contentTypegerekir false.


1
Bunu AJAX olmadan da nasıl yapacağınızı biliyor musunuz?
William Entriken

@FullDecent Ne demek istiyorsun? Kullanıcıdan Dosya API'sını kullanarak bir dosya indirmesini istemek için? Veya sadece blob içeriğini depolamak için?
Fabrício Matté

4
Temelde yapılacak$('input[type=file]').value=blob
William Entriken

14
Güvenlik gereksinimleri, dosya girdi değerlerinin programlı olarak ayarlanmasını engeller: stackoverflow.com/questions/1696877/…
2013

9
Dosyanın aksine, bir Blob'un sunucuya gönderildiğinde genel bir dosya adına sahip olduğuna dikkat edin. Ancak Blob dosya adını FormData'da söyleyebilirsiniz: stackoverflow.com/questions/6664967/…
Sebastien Lorber

20

Aslında , sunucuya JavaScript'ten FormDataa göndermek için kullanmanız gerekmez Blob(ve a Fileda a'dır Blob).

jQuery örneği:

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

Vanilya JavaScript örneği:

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

Geleneksel bir HTML çok parçalı formunu bir "AJAX" uygulamasıyla değiştiriyorsanız (yani, arka ucunuz çok parçalı form verilerini kullanıyorsa), FormDatanesneyi başka bir yanıtta açıklandığı gibi kullanmak istersiniz .

Kaynak: XMLHttpRequest2'deki Yeni Hileler | HTML5 Rocks


17

Yukarıdaki örneği blob'larla çalışmak için alamadım ve upload.php'de tam olarak ne olduğunu bilmek istedim. İşte gidiyorsun:

(yalnızca Chrome 28.0.1500.95'te test edilmiştir)

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

}

Upload.php'nin içeriği:

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

İşlev çağrısındaki satırı data: fd,olarak değiştirebileceğinizden oldukça eminim . ajaxdata: blob,
Kenny Evitt

11

@Yeeking örneğini FormData kullanmadan, blob'u transfer etmek için javascript nesnesi kullanarak çalışmayı başardım. Recorder.js kullanılarak oluşturulan bir ses blobuyla çalışır. Chrome 32.0.1700.107 sürümünde test edildi

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'nin içeriği

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

7
Php dosyasında dikkatli olun - HTTP istemcisinin dosya adını belirlemesine izin verirseniz, kötü amaçlı içeriği seçtikleri bir dosyaya ve dizine yüklemek için kullanabilir. (Apaçi oraya yazabildiği sürece)
2014

9

2019 Güncellemesi

Bu, yanıtları en son Fetch API ile günceller ve jQuery'ye ihtiyaç duymaz.

Sorumluluk reddi: IE, Opera Mini ve daha eski tarayıcılarda çalışmaz. Caniuse bakın .

Temel Getirme

Şu kadar basit olabilir:

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

Hata İşlemeyle Getir

Hata işlemeyi ekledikten sonra şöyle görünebilir:

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 Kodu

Bu, upload.php'deki sunucu tarafı kodudur.

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

2

Yukarıdaki tüm çözümleri ve ek olarak ilgili cevaplarda olanları da denedim. Blob'u manuel olarak bir HTMLInputElement'in file özelliğine geçirmeyi, FileReader'daki tüm readAs * yöntemlerini çağırmayı, bir FormData.append çağrısı için ikinci argüman olarak bir File örneğini kullanarak, blob verilerini elde ederek bir dize olarak almaya çalışmayı içeren ancak bunlarla sınırlı olmayan çözümler URL.createObjectURL (myBlob) adresindeki değerler kötü çıktı ve makinemi çöktü.

Şimdi, bunları veya daha fazlasını denerseniz ve yine de blobunuzu yükleyemediğinizi fark ederseniz, sorunun sunucu tarafı olduğu anlamına gelebilir. Benim durumumda, blobum PHP.INI'de http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize ve post_max_size sınırını aştığı için dosya ön uçtan çıkıyordu form ancak sunucu tarafından reddediliyor. Bu değeri doğrudan PHP.INI'de veya .htaccess aracılığıyla artırabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.