この構造にはblobデータがあります。
Blob {type: "audio/wav", size: 655404, slice: function}
size: 655404
type: "audio/wav"
__proto__: Blob
実際には、最近のChrome getUerMedia()
および Recorder.js を使用して記録されたサウンドデータです。
Jqueryのpostメソッドを使用してこのblobをサーバーにアップロードするにはどうすればよいですか?私は運なしでこれを試しました:
$.post('http://localhost/upload.php', { fname: "test.wav", data: soundBlob },
function(responseText) {
console.log(responseText);
});
これを試して
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 を使用し、jQuery.ajax
のprocessData
およびcontentType
をfalse
に設定する必要があります。
上記の例を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);
}
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);
?>
実際、FormData
を使用してJavaScriptからBlob
をサーバーに送信する必要はありません(また、File
は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
});
バニラ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);
確かに、従来のHTMLマルチパートフォームを「AJAX」実装に置き換える場合(つまり、バックエンドがマルチパートフォームデータを消費する場合)、別の回答で説明されているFormData
オブジェクトを使用する必要があります。
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);
}
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);
?>
これにより、最新の Fetch API で回答が更新され、jQueryは必要ありません。
免責事項:IE、Opera Miniおよび古いブラウザーでは動作しません。 caniuse を参照してください。
基本的なフェッチ
それは次のように簡単かもしれません:
fetch(`https://example.com/upload.php`, {method:"POST", body:blobData})
.then(response => console.log(response.text()))
エラー処理を伴うフェッチ
エラー処理を追加すると、次のようになります。
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コード
これは、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);
?>
上記のすべてのソリューションと、関連する回答のソリューションも試しました。 blobをHTMLInputElementのファイルプロパティに手動で渡すこと、FileReaderのすべてのreadAs *メソッドを呼び出すこと、FormData.append呼び出しの2番目の引数としてFileインスタンスを使用すること、blobデータを文字列として取得することを含むURL.createObjectURL(myBlob)の値が原因で、マシンが厄介でクラッシュしました。
さて、もしそれらを試したが、まだblobをアップロードできない場合、問題はサーバー側にある可能性があります。私の場合、私のblobは http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize およびPHP.INIのpost_max_sizeの制限を超えていたため、ファイルはフロントエンドフォームを離れていましたが、サーバーによって拒否されました。この値は、PHP.INIで直接増やすか、.htaccessで増やすことができます。