admin管理员组

文章数量:1355570

Chrome Build: the newest, 33+

A Chrome Extension extracts certain urls from currently viewed site and then downloads a subset of them (quite often hundreds of files).

Expected Behavior:

Files are downloaded into the default Download-Folder without questioning where and under which filename they have to be saved.

Problem:

If a user has enabled the option "Ask where to save each file before downloading" in Chrome->Settings->Advanced Settings->Downloads then when trying to download, for example, 100 files simultaniously, Chrome tries to open 100 SaveAs Dialogs and crashes.

What I tried:

  • to use chrome.downloads.download(object options, function callback) method with an option saveAs: false
  • using the following code to trigger a download through an emulated mousevent:

    function saveAs(Url,filename){
      var blob=new Blob([''], {type:'application/octet-stream'}); 
      var url = webkitURL.createObjectURL(blob);
      var a = document.createElementNS('','a');
      a.href = Url;
      a.download = filename; 
      var e = document.createEvent('MouseEvents');
      e.initMouseEvent('click', false, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
      a.dispatchEvent(e);
      webkitURL.revokeObjectURL(url);
    }
    

Chrome Build: the newest, 33+

A Chrome Extension extracts certain urls from currently viewed site and then downloads a subset of them (quite often hundreds of files).

Expected Behavior:

Files are downloaded into the default Download-Folder without questioning where and under which filename they have to be saved.

Problem:

If a user has enabled the option "Ask where to save each file before downloading" in Chrome->Settings->Advanced Settings->Downloads then when trying to download, for example, 100 files simultaniously, Chrome tries to open 100 SaveAs Dialogs and crashes.

What I tried:

  • to use chrome.downloads.download(object options, function callback) method with an option saveAs: false
  • using the following code to trigger a download through an emulated mousevent:

    function saveAs(Url,filename){
      var blob=new Blob([''], {type:'application/octet-stream'}); 
      var url = webkitURL.createObjectURL(blob);
      var a = document.createElementNS('http://www.w3/1999/xhtml','a');
      a.href = Url;
      a.download = filename; 
      var e = document.createEvent('MouseEvents');
      e.initMouseEvent('click', false, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
      a.dispatchEvent(e);
      webkitURL.revokeObjectURL(url);
    }
    
Share Improve this question edited Aug 30, 2014 at 19:56 AstroCB 12.4k20 gold badges59 silver badges74 bronze badges asked Jan 4, 2014 at 18:51 QuteBitsQuteBits 1631 gold badge1 silver badge10 bronze badges 5
  • 3 i've never worked on a chrome extension, but from previous experience in using apps in chrome, user defined preferences will always take precedence over app behaviour. it'd be a security flaw if apps were allowed to override something a user has explicitly clicked. – royse41 Commented Jan 5, 2014 at 13:14
  • 1 could you post these to a service, have it generate a zip, give you back the URL or the b64, and then download that zip? then, only one popup? – oooyaya Commented Jan 6, 2014 at 20:45
  • say whaaaat? :D i totally dig the way you think but no man, it seems to be more adequate to inform the user that all it takes is to uncheck one setting or not try to download 100 items at a time than to force the user to unzip stuff after each download. Moreover, that behavior is counterintuitive - so the user would have to be informed about it anyways. I think there has to be a more elegant solution. – QuteBits Commented Jan 6, 2014 at 23:15
  • 1 It might be a bug that it pops up the Save As dialog even if an extension with the downloads permission says not to. File a bug at crbug./new? – Jeffrey Yasskin Commented Mar 24, 2014 at 1:31
  • I've checked it on the newest build (35.0.1897.2 dev-m) - it seems that You were right and it was a bug. Both approaches work as expected. Could You please place Your answer as an actual answer and not as a ment? In that way I can mark it as the right answer. – QuteBits Commented Mar 24, 2014 at 23:51
Add a ment  | 

2 Answers 2

Reset to default 1

It is impossible when "Ask where to save each file before downloading" Enabled (as of 70.0.3538.77). The corresponding Chromium bug is:

Bug 417112: chrome.downloads.download ignore saveAs

Moreover setting filename in chrome.downloads.downloads() also doesn't work.

Bug 758094: Extension can not rename downloaded file

Edit : I've added plete sample code for multiple file downloads which doesn't show SaveAs Dialog.

You can achieve this by using chrome.downloads API.

manifest.json

{
  "description": "Multiple file downloads without showing SaveAs Dialog",
  "background": {
     "scripts": [ "background.js" ],
     "persistent" : true
  },
  "content_scripts": [{
     "js": [ "content_script.js"],
     "matches": [ "<all_urls>" ],
     "run_at": "document_start"
  }],
  "manifest_version": 2,
  "name": "MultipleFileDownloads",
  "permissions": [ "downloads" ],
  "short_name": "MFD",
  "version": "0.0.0.1"
}

content_script.js

var DOWNLOAD_LIMIT = 100;

function downloadURL(url, filename, callback){
    chrome.runtime.sendMessage({
        download_url : url,
        filename : filename
    },function(){
        if(typeof callback == 'function'){
            callback();
        }
    })
}

function simulateFileDownload(i){
    if(i > DOWNLOAD_LIMIT){
        document.getElementById('download_btn').disabled = false;
        return false;
    }
    var blob = new Blob(['This is sample file '+i], {type:'text/plain'});
    var url = URL.createObjectURL(blob);
    downloadURL(url,'Sample-'+i+'.txt',function(){
        URL.revokeObjectURL(url);
        i++;
        simulateFileDownload(i);
    })
}

window.onload = function(){
    var btn = document.createElement('button');
    btn.id = 'download_btn';
    btn.style.cssText = 'position:fixed;top:10px;left:10px;width:140px;height:30px;z-index:1000000;';
    btn.textContent = 'Download Files';
    document.body.appendChild(btn);
    btn.addEventListener('click',function(){
        this.disabled = true;
        simulateFileDownload(0);
    })
}

background.js

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
    if(message.download_url){
        chrome.downloads.download({
            url : message.download_url,
            filename : message.filename,
            saveAs : false
        })
    }
});

本文标签: javascriptHow to force Chrome to NOT open SaveAs Dialog when downloading a URLStack Overflow