2011-07-27 16 views
28

我需要將dataURL轉換爲JavaScript中的文件對象,以便使用ajax發送它。可能嗎?如果是,請告訴我如何。謝謝。如何將dataURL轉換爲JavaScript中的文件對象?

更新:
謝謝你的所有答案。不過,這是一個很老的問題,我認爲它現在已經收集了足夠多的答案。

+0

你需要給我們更多。 – cwallenpoole

+0

cwallenpoole,它的一個大代碼,它的一切工作都很好,因爲圖像被附加到身體,只是告訴我你需要什麼,我會在這裏發佈 – kapv89

+0

什麼是你的腳本/頁面中的formData? –

回答

38

如果您需要通過ajax發送它,則不需要使用File對象,只需要BlobFormData對象。

正如我注意到的那樣,爲什麼不直接通過ajax發送base64字符串到服務器並將其轉換爲二進制服務器端,例如使用PHP的base64_decode?無論如何,在Chrome中13 this answer作品和,WebKit Nightlies版的標準兼容代碼:

function dataURItoBlob(dataURI) { 
    // convert base64 to raw binary data held in a string 
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this 
    var byteString = atob(dataURI.split(',')[1]); 

    // separate out the mime component 
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 

    // write the bytes of the string to an ArrayBuffer 
    var ab = new ArrayBuffer(byteString.length); 
    var ia = new Uint8Array(ab); 
    for (var i = 0; i < byteString.length; i++) { 
     ia[i] = byteString.charCodeAt(i); 
    } 

    //Old Code 
    //write the ArrayBuffer to a blob, and you're done 
    //var bb = new BlobBuilder(); 
    //bb.append(ab); 
    //return bb.getBlob(mimeString); 

    //New Code 
    return new Blob([ab], {type: mimeString}); 


} 

然後,只需團塊附加到一個新的FORMDATA對象,並用ajax郵寄到您的服務器:

var blob = dataURItoBlob(someDataUrl); 
var fd = new FormData(document.forms[0]); 
var xhr = new XMLHttpRequest(); 

fd.append("myFile", blob); 
xhr.open('POST', '/', true); 
xhr.send(fd); 
+1

謝謝你的回答,不過,我已經做了這樣的事情,它工作正常。它是基於畫布的圖像縮放器,水印和上傳器。等待項目使用它 – kapv89

+0

在Firefox中,如果沒有窗體,FormData應該創建爲:'new FormData();否則它會拋出異常。 –

+0

爲什麼你在這裏有一個'callback'參數?看來你應該刪除它。 –

29

BlobBuilder已棄用,因此不應再使用。使用Blob而不是舊的BlobBuilder。代碼非常乾淨簡單。

文件對象是從Blob對象繼承的。您可以將它們與FormData對象一起使用。

function dataURLtoBlob(dataurl) { 
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], 
     bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); 
    while(n--){ 
     u8arr[n] = bstr.charCodeAt(n); 
    } 
    return new Blob([u8arr], {type:mime}); 
} 

使用dataURLtoBlob()函數將dataURL轉換爲blob並將ajax發送到服務器。

例如:

var dataurl = 'data:text/plain;base64,aGVsbG8gd29ybGQ='; 
var blob = dataURLtoBlob(dataurl); 
var fd = new FormData(); 
fd.append("file", blob, "hello.txt"); 
var xhr = new XMLHttpRequest(); 
xhr.open('POST', '/server.php', true); 
xhr.onload = function(){ 
    alert('upload complete'); 
}; 
xhr.send(fd); 

另一種方式:

您還可以使用fetch一個URL轉換爲一個文件對象(文件對象名/文件名的財產,這是不同於斑點物體)

該代碼非常簡短,易於使用。 (works in Chrome and Firefox)

//load src and convert to a File instance object 
//work for any type of src, not only image src. 
//return a promise that resolves with a File instance 

function srcToFile(src, fileName, mimeType){ 
    return (fetch(src) 
     .then(function(res){return res.arrayBuffer();}) 
     .then(function(buf){return new File([buf], fileName, {type:mimeType});}) 
    ); 
} 

用法示例1:只是轉換爲文件對象

srcToFile(
    'data:text/plain;base64,aGVsbG8gd29ybGQ=', 
    'hello.txt', 
    'text/plain' 
) 
.then(function(file){ 
    console.log(file); 
}) 

用法示例2:轉換爲文件對象,並上傳到服務器

srcToFile(
    'data:text/plain;base64,aGVsbG8gd29ybGQ=', 
    'hello.txt', 
    'text/plain' 
) 
.then(function(file){ 
    console.log(file); 
    var fd = new FormData(); 
    fd.append("file", file); 
    return fetch('/server.php', {method:'POST', body:fd}); 
}) 
.then(function(res){ 
    return res.text(); 
}) 
.then(console.log) 
.catch(console.error) 
; 
+2

我真的很喜歡你的答案,因爲它是整潔乾淨,但我真的可以找出在其他答案中使用ArrayBuffer。如果ArrayBuffer以及爲什麼不在這裏使用,請您解釋一下使用情況? – Ali

+0

很喜歡!最好的回答 –

1

一些研究,我到達之後一個:

function dataURItoBlob(dataURI) { 
 
    // convert base64 to raw binary data held in a string 
 
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this 
 
    var byteString = atob(dataURI.split(',')[1]); 
 
    // separate out the mime component 
 
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 
 
    // write the bytes of the string to an ArrayBuffer 
 
    var ab = new ArrayBuffer(byteString.length); 
 
    var dw = new DataView(ab); 
 
    for(var i = 0; i < byteString.length; i++) { 
 
     dw.setUint8(i, byteString.charCodeAt(i)); 
 
    } 
 
    // write the ArrayBuffer to a blob, and you're done 
 
    return new Blob([ab], {type: mimeString}); 
 
} 
 

 
module.exports = dataURItoBlob;

相關問題