javascript - extensiones - Hacer una extensión de Chrome descargar un archivo
extensiones chrome (5)
Estoy creando una extensión que descargará un archivo mp3 de un sitio web. Intento hacer esto creando una nueva pestaña con el enlace al archivo mp3, pero Chrome sigue abriéndolo dentro del reproductor en lugar de descargarlo. ¿Hay alguna manera de que pueda crear una ventana emergente para pedirle al usuario que "guarde como" el archivo?
Aquí hay una forma concisa de descargar un archivo usando el permiso de "descargas" en el manifiesto de Chrome usando la solución de @Xan y @ 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"
});
Esta es una versión ligeramente modificada de la respuesta de @Steve Mc que simplemente lo convierte en una función generalizada que se puede copiar y usar fácilmente tal cual:
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
}
Lo hice de la siguiente manera en el código de Appmator en Github .
El enfoque básico es construir tu Blob, como quieras (Chrome tiene un responseBlob en XmlHttpRequest para que puedas usar eso), crea un iframe (hidden, display:none
) y luego asigna el src del iframe para que sea el Blob.
Esto iniciará una descarga y la guardará en el sistema de archivos. El único problema es que aún no puedes configurar el nombre de archivo.
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);
Un ejemplo del uso de responseBlob de XmlHttpRequest (ver: 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);
}
Usé una variación de la solución 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
}
Una cosa que debes tener en cuenta es que este código debe ejecutarse en la página y no en tu extensión; de lo contrario, el usuario no verá la acción de descarga que hace Chrome. La descarga seguirá ocurriendo y podrá verla en la pestaña de descarga, pero no verán la descarga real.
Editar (después de pensar en hacer que su código se ejecute en la página de contenido):
La forma en que realiza una acción en la página de contenido en lugar de hacerlo en su extensión es usar el " envío de mensajes" de Chrome. Básicamente, pasa un mensaje de su extensión (que es casi como una página separada) a la página de contenido con la que está trabajando la extensión. Luego tiene un oyente que su extensión ha inyectado en la página de contenido que reacciona al mensaje y realiza la descarga. Algo como esto:
chrome.extension.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.greeting == "hello") {
try{
downloadCSS();
}
catch (err) {
alert("Error: "+err.message);
}
}
});
Avance rápido 3 años, y ahora Google Chrome ofrece la API chrome.downloads
(desde Chrome 31).
Después de declarar el permiso "downloads"
en el manifiesto, puede iniciar una descarga con esta llamada:
chrome.downloads.download({
url: "http://your.url/to/download",
filename: "suggested/filename/with/relative.path" // Optional
});
Si desea generar el contenido del archivo en el script, puede usar las API de Blob
y URL
, por ejemplo:
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
//...
});
Para ver más opciones (por ejemplo, cuadro de diálogo Guardar como, sobrescribir archivos existentes, etc.), consulte la documentation .