자바 스크립트는 어떻게 Blob을 업로드 할 수 있나요?
이 구조에 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);
?>
실제로 JavaScript에서 서버 FormData
로 a를 보내는 데 사용할 필요가 없습니다 Blob
(그리고 a 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
});
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);
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
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);
?>
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);
?>
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
참고URL : https://stackoverflow.com/questions/13333378/how-can-javascript-upload-a-blob
'development' 카테고리의 다른 글
mongodb 여러 배열 항목으로 찾기 (0) | 2020.09.03 |
---|---|
Git Bash가 내 PATH를 보지 못함 (0) | 2020.09.03 |
SQLite INSERT-ON DUPLICATE KEY UPDATE (UPSERT) (0) | 2020.09.03 |
PHP에서 문자열의 시작 부분에 추가하기 위해. =에 해당하는 것이 있습니까? (0) | 2020.09.03 |
C #의 네임 스페이스와 Java의 패키지의 차이점 (0) | 2020.09.03 |