6

我試圖在Chrome擴展中下載多個文件。以下代碼創建一個到文件的虛擬鏈接,然後觸發下載該文件的.click()事件。 問題是隻有第一個.click()事件觸發下載。後續的.click()事件被忽略。JavaScript click()方法只能在Chrome擴展中運行一次

這裏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 
} 

這裏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"}); 
}); 

我已經試過:

驚訝爲什麼很難簡單地保存多個文件。感謝任何幫助。

+1

等了幾個月,和['chrome.downloads'](https://developer.chrome.com/dev/extensions/downloads。HTML)API廣泛可用。關於CSP錯誤:'a'是一個鏈接,其'toString'屬性返回鏈接的目標。所以,如果你使用'setTimeout(a,300);',它會嘗試評估鏈接的目標。字符串作爲代碼評估是默認禁止的,所以你會得到錯誤。但是,如果使用'setTimeout(function(){a.click();},300);',該文件仍然沒有被下載。 –

+0

您是否找到解決此問題的臨時解決方案? – coneybeare

+0

我認爲這是不可能的安全問題。如果可能的話,那麼事實上我可以打開無限彈出/下載只需點擊一下。 –

回答

0

而不是使用.live()梅索德,因此不再建議嘗試.on()

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

這裏是documentation

+0

感謝您的提示,但不幸的是,這並沒有幫助。 – toby88

4

的訣竅是不使用element.click方法,而是創建多個MouseEvent。爲此,每次需要點擊時,您都需要創建一個MouseEvent

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. 

當使用Chrome的這個方法雖然,你從瀏覽器要求警告「此網站試圖下載多個文件。你要允許這樣做?[禁止] [允許]」。因此,如果您在擴展程序的後臺頁面中執行此操作,後臺頁面會收到警告,但用戶看不到它,因此用戶無法單擊「允許」。

解決方法是創建一個「點擊」錨點的選項卡。事情是這樣的:

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 }); 

對於這項工作,擴展必須具有"tabs"作爲的manifest.json一個permission。您可以調整超時以關閉該選項卡,但是,如果您關閉它太快,則不會發生下載。

+0

我對此抱有很高的期望,但Chrome瀏覽器仍然屏蔽了多個發送事件。我不是試圖在相同的鏈接上點擊3次,而是3個不同的鏈接,甚至不一定在同一頁面上。只有第一個在這裏「點擊」 – coneybeare

+0

我想我明白你的意思。嘗試在元素上使用MouseEvent/dispatchEvent,而不將其添加到/從文檔中移除。因此,只需創建它,分配屬性並分派事件,而無需追加/刪除。我只是在Chrome 25.0.1364.172上試過,它對我很有用。 – zertosh

+0

有沒有辦法創建一個元素而不添加它? createElement()似乎可以兼得。 – coneybeare