2011-01-30 61 views
27

我正在創建一個擴展程序,用於從網站下載mp3文件。我正在嘗試通過創建一個帶有mp3文件鏈接的新選項卡來實現此目的,但chrome不斷在播放器中打開它,而不是下載它。有什麼辦法可以創建彈出窗口來要求用戶「保存」爲文件?製作Chrome擴展程序下載文件

+2

看到http://stackoverflow.com/questions/399486/open-該保存圖像對話框使用jquery-javascript – serg 2011-01-31 01:44:36

回答

64

快進3年,現在Google Chrome提供chrome.downloads API(自Chrome 31以來)。

在清單申報"downloads"許可後,可以啓動下載使用該調用:

chrome.downloads.download({ 
    url: "http://your.url/to/download", 
    filename: "suggested/filename/with/relative.path" // Optional 
}); 

如果要生成的腳本文件內容,你可以使用BlobURL的API,如:

var blob = new Blob(["array of", " parts of ", "text file"], {type: "text/plain"}); 
var url = URL.createObjectURL(blob); 
chrome.downloads.download({ 
    url: url // The object URL can be used as download URL 
    //... 
}); 

更多選項(即另存爲對話框,覆蓋現有文件等),看documentation

5

我做了如下Appmator代碼Github

基本的方法是建立你的Blob,然而你想要的(Chrome在XmlHttpRequest上有一個responseBlob,所以你可以使用它),創建一個iframe(隱藏,display:none),然後指定iframe的src作爲Blob。

這將啓動下載並將其保存到文件系統。唯一的問題是,你不能設置文件名。

var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)(); 

var output = Builder.output({"binary":true}); 
var ui8a = new Uint8Array(output.length); 

for(var i = 0; i< output.length; i++) { 
    ui8a[i] = output.charCodeAt(i); 
} 

bb.append(ui8a.buffer); 

var blob = bb.getBlob("application/octet-stream"); 
var saveas = document.createElement("iframe"); 
saveas.style.display = "none"; 

if(!!window.createObjectURL == false) { 
    saveas.src = window.webkitURL.createObjectURL(blob); 
} 
else { 
    saveas.src = window.createObjectURL(blob); 
} 

document.body.appendChild(saveas); 

使用XMLHttpRequest的responseBlob的例子(見:http://www.w3.org/TR/XMLHttpRequest2/#dom-xmlhttprequest-responseblob

var xhr = new XmlHttpRequest(); 
xhr.overrideMimeType("application/octet-stream"); // Or what ever mimeType you want. 
xhr.onreadystatechanged = function() { 
if(xhr.readyState == 4 && xhr.status == 200) { 

    var blob = xhr.responseBlob(); 
    var saveas = document.createElement("iframe"); 
    saveas.style.display = "none"; 

    if(!!window.createObjectURL == false) { 
    saveas.src = window.webkitURL.createObjectURL(blob); 
    } 
    else { 
    saveas.src = window.createObjectURL(blob); 
    } 

    document.body.appendChild(saveas); 
} 
+0

該代碼的第一行的目的是什麼? – 2011-05-19 20:37:45

+0

這是一個很好的觀點。 – Kinlan 2011-05-20 13:28:28

+0

我在哪裏指定我想下載的文件? – 2011-05-21 01:39:26

13

我用的解決方案,你需要記住裸露here

var downloadCSS = function() { 
    window.URL = window.webkitURL || window.URL; 
    file = new BlobBuilder(); //we used to need to check for 'WebKitBlobBuilder' here - but no need anymore 
    file.append(someTextVar); //populate the file with whatever text it is that you want 
    var a = document.createElement('a'); 
    a.href = window.URL.createObjectURL(file.getBlob('text/plain')); 
    a.download = 'combined.css'; // set the file name 
    a.style.display = 'none'; 
    document.body.appendChild(a); 
    a.click(); //this is probably the key - simulatating a click on a download link 
    delete a;// we don't need this anymore 
} 

一件事是,變化這段代碼需要在頁面上執行,而不是在你的擴展中執行 - 否則用戶將看不到chrome所做的下載操作。下載仍然會發生,您將能夠在下載選項卡中看到它,但他們不會看到實際的下載發生。

編輯(約使您的代碼事後執行內容頁):

你做出一個行動的方式出現的內容頁面,而不是您的分機使用Chrome "message passing"上。基本上,您將來自您的擴展(這幾乎就像一個單獨的頁面)的消息傳遞到擴展正在使用的內容頁面。然後你有一個監聽器,你的擴展已經注入了對消息作出反應並進行下載的內容頁面。事情是這樣的:

chrome.extension.onMessage.addListener(
    function (request, sender, sendResponse) { 
     if (request.greeting == "hello") { 
      try{ 
       downloadCSS(); 
      } 
      catch (err) { 
       alert("Error: "+err.message); 
      } 
     } 
    }); 
10

這@Steve三菱商事的答案略加修改的版本,只是使它成很容易被複制,並用作廣義函數是:

function exportInputs() { 
    downloadFileFromText('inputs.ini','dummy content!!') 
} 

function downloadFileFromText(filename, content) { 
    var a = document.createElement('a'); 
    var blob = new Blob([ content ], {type : "text/plain;charset=UTF-8"}); 
    a.href = window.URL.createObjectURL(blob); 
    a.download = filename; 
    a.style.display = 'none'; 
    document.body.appendChild(a); 
    a.click(); //this is probably the key - simulating a click on a download link 
    delete a;// we don't need this anymore 
} 
1

下面是使用「下載」,下載文件的簡潔的方式在Chrome許可使用@Xan表現和@ AmanicA的解決方案

function downloadFile(options) { 
    if(!options.url) { 
     var blob = new Blob([ options.content ], {type : "text/plain;charset=UTF-8"}); 
     options.url = window.URL.createObjectURL(blob); 
    } 
    chrome.downloads.download({ 
     url: options.url, 
     filename: options.filename 
    }) 
} 

// Download file with custom content 
downloadFile({ 
    filename: "foo.txt", 
    content: "bar" 
}); 

// Download file from external host 
downloadFile({ 
    filename: "foo.txt", 
    url: "http://your.url/to/download" 
}); 
相關問題