6

Ich versuche, mehrere Dateien in einer Chrome-Erweiterung herunterzuladen. Der folgende Code erstellt eine Dummy-Verknüpfung zu einer Datei und löst dann das Ereignis .click() aus, das die Datei herunterlädt. Das Problem ist, dass nur das erste .click() Ereignis einen Download auslöst. Nachfolgende .click() - Ereignisse werden ignoriert.JavaScript click() -Methode funktioniert nur einmal in der Chrome-Erweiterung

Hier die manifest.json:

{ 
    "name": "Simple File Downloader", 
    "version": "0.1", 
    "permissions": ["contextMenus", "http://*/"], 
    "background": { 
    "persistent": false, 
    "scripts": ["sample.js"] 
    }, 
    "content_security_policy": "script-src 'self'; object-src 'self'", 
    "manifest_version": 2 
} 

Hier die Sample.js:

function onClickHandler(info, tab) { 
    var a = document.createElement('a'); 
    a.href = 'http://or.cdn.sstatic.net/chat/so.mp3'; 
    a.download = 'so.mp3'; 
    document.body.appendChild(a); 
    a.click(); // this click triggers the download 
    // this timeout violates content security policy 
    // setTimeout(a, 300); 
    a.click(); // this click doesn't do anything 
    document.body.removeChild(a); 

    a = document.createElement('a'); 
    a.href = 'http://or.cdn.sstatic.net/chat/so.mp3'; 
    a.download = 'so.mp3'; 
    document.body.appendChild(a); 
    a.click(); // this click doesn't do anything either 
    document.body.removeChild(a); 
}; 

chrome.contextMenus.onClicked.addListener(onClickHandler); 
chrome.runtime.onInstalled.addListener(function() { 
    chrome.contextMenus.create({"title": "Download File", "id":"download_file"}); 
}); 

Ich habe versucht:

Überrascht, warum es so schwer ist, einfach mehrere Dateien zu speichern. Schätze jede Hilfe.

+1

Warten Sie ein paar Monate und die ['chrome.downloads'] (https://developer.chrome.com/dev/extensions/downloads.html) API ist weit verbreitet. Über den CSP-Fehler: 'a' ist eine Verknüpfung, deren' toString' -Eigenschaft das Ziel der Verknüpfung zurückgibt. Wenn Sie also 'setTimeout (a, 300);' verwenden, versucht es, das Ziel der Verbindung zu bewerten. String-as-code-Auswertung ist standardmäßig nicht zulässig, daher erhalten Sie den Fehler. Wenn Sie 'setTimeout (function() {a.click();}, 300);' verwenden, wird die Datei immer noch nicht heruntergeladen. –

+0

Haben Sie eine temporäre Lösung für dieses Problem gefunden? – coneybeare

+0

Ich denke, es ist kein Sicherheitsproblem möglich. Wenn es möglich wäre, dann könnte ich praktisch unendlich Popup/Download mit einem einzigen Klick öffnen. –

Antwort

0

Statt die .live() Methode zu verwenden, die nicht mehr versuchen wird empfohlen .on()

$(document).on("click", "a", function(event){ 
    // do whatever 
}); 

hier die documentation

+0

Danke für den Tipp, aber leider hat das nicht geholfen. – toby88

4

ist der Trick nicht die element.click Methode zu verwenden ist, sondern mehrere MouseEvent zu erstellen. Damit dies funktioniert, müssen Sie für jeden Klick ein MouseEvent erstellen.

function clicker(el, clickCount) { 
    var mousedownEvent; 
    while(clickCount--) { 
    mousedownEvent = document.createEvent("MouseEvent"); 
    mousedownEvent.initMouseEvent("click", true, true, window, 0, null, null, null, null, false , false, false, false, 0, null); 
    el.dispatchEvent(mousedownEvent); 
    } 
} 

clicker(a, 3); 
// your anchor 'a' gets clicked on 3 times. 

Wenn diese Methode in Chrome obwohl, erhalten Sie eine Warnung aus dem Browser zu fragen „Diese Seite mehrere Dateien zum Download versucht. Wollen Sie dies zulassen? [Verweigern] [Zulassen]“. Wenn Sie dies auf der Hintergrundseite einer Erweiterung tun, erhält die Hintergrundseite die Warnung, die der Benutzer nicht sehen kann. Der Benutzer kann also nicht auf "Zulassen" klicken.

Eine (grobe/böse) Problemumgehung besteht darin, eine Registerkarte zu erstellen, die auf den Anker "klickt". Etwas wie folgt aus:

function _anchorDownloader(url, filename) { 
    var timeout = 500; 
    return 'javascript:\'<!doctype html><html>'+ 
    '<head></head>' + 
    '<script>' + 
     'function initDownload() {'+ 
     'var el = document.getElementById("anchor");'+ 
     'el.click();' + 
     'setTimeout(function() { window.close(); }, ' + timeout + ');' + 
     '}'+ 
    '</script>' + 
    '<body onload="initDownload()">' + 
     '<a id="anchor" href="' + url + '" download="'+ filename + '"></a>'+ 
    '</body>' + 
    '</html>\''; 
}; 

function downloadResource(info, tab) { 
    // ... 
    chrome.tabs.create({ 'url' : _anchorDownloader(url, filename), 'active' : false }); 
    // ... 
} 

chrome.contextMenus.create({"title": "Save Image…", "contexts":["image"], "onclick": downloadResource }); 

Damit dies funktioniert, muss die Erweiterung "tabs" als permission im manifest.json haben. Sie können das Zeitlimit anpassen, um die Registerkarte zu schließen. Wenn Sie es jedoch zu schnell schließen, wird kein Download ausgeführt.

+0

Ich hatte große Hoffnungen dafür, aber es scheint, dass Chrome immer noch mehr als eine Dispatch-Veranstaltung blockiert. Ich versuche nicht 3 mal auf denselben Link zu "klicken", sondern 3 verschiedene, nicht unbedingt auf derselben Seite. Nur der erste wird hier "geklickt" – coneybeare

+0

Ich glaube ich verstehe was du meinst. Versuchen Sie MouseEvent/dispatchEvent für das Element, ohne es an das Dokument anzuhängen oder aus dem Dokument zu entfernen. Also erstellen Sie es einfach, weisen Sie die Eigenschaften zu und senden Sie das Ereignis, ohne jemals anzuhängen/entfernen. Ich habe es gerade auf Chrome 25.0.1364.172 versucht und es hat für mich funktioniert. – zertosh

+0

Gibt es eine Möglichkeit, ein Element zu erstellen und es nicht hinzuzufügen? createElement() scheint beides zu tun. – coneybeare

Verwandte Themen