7

I am trying to download a file (image) from a URL via a Chrome Extension using chrome.downloads, but for some reason chrome.downloads is undefined (getting the warning: Cannot read property 'download' of undefined). I am basing my attempt on example from Google.

My test-extension does not have any popup, just a basic manifest and an extremely simply JavaScript file.

manifest.json:

{
    "manifest_version": 2,
    "name": "Testing chrome.downloads.download",
    "version": "0.0.1",
    "permissions": [
        "activeTab",
        "downloads",
        "<all_urls>"
    ],
    "content_scripts": [{
        "matches": [
            "http://www.example.com/*"
        ],
        "js": [
            "jquery.js",
            "index.js"
        ]
    }]
}

index.js:

$(document).ready(function () {
  link = 'http://example.com/image.jpg';
  chrome.downloads.download({
    url: link,
    filename: './' + link.substr(link.lastIndexOf('/')+1),
    saveAs: false
  });
});

So, how can I make this work?

Makyen
  • 31,849
  • 12
  • 86
  • 121
EricC
  • 5,720
  • 13
  • 52
  • 71
  • i dont really know but i would try changing the link to https://codepo8.github.io/canvas-images-and-pixels/img/horse.png – Rico Mar 24 '17 at 09:14
  • Code and manifest seems ok to me. What application are you using to test your extension (desktop chrome, perhaphs?)? What version are you using? – Wikiti Mar 24 '17 at 09:18
  • @Rico, the link I actually use is a valid image link on the website I want to download from. But that does not matter, the problem is that `chrome.downloads` is undefined... – EricC Mar 24 '17 at 09:53
  • @Wikiti I'm using chrome canary browser version 59.0.3048.0 canary (64-bit) for Mac... – EricC Mar 24 '17 at 09:56
  • http://stackoverflow.com/questions/21317476/how-to-use-jquery-in-chrome-extension << check this – Rico Mar 24 '17 at 09:57
  • in answer i will post how i did it, ok? – Rico Mar 24 '17 at 10:15

2 Answers2

12

So after some research i see content scripts dont directly support downloads, but you can pass message to your background page which supports download. The reason i included background page was to be able to see the console ;) you can try to directly goto background.js

manifest.json

{
  "name": "Download static images",
  "description": "Downloads images defined with <img> tag from watched webpage(s) by injecting a script",
  "version": "1.0",
  "browser_action": {
    "default_icon": "debuggerPause.png",
    "default_title": "get page html"
  },
  "background": {
    "page": "background.html"
  },
  "content_scripts": [
    {
      "matches": ["http://stackoverflow.com/*"],
      "js": ["main.js"]
    }
  ],
  "permissions": [
      "tabs", 
      "background","downloads"
  ],
  "manifest_version": 2
}

main.js

function getHtml() {
  var pagehtml = document.documentElement;
  var imgs=pagehtml.getElementsByTagName( 'img' );
  var pass_array=[];
  for (i in imgs){
    pass_array.push(imgs[i]["currentSrc"]);
  }
  console.log(pass_array);
  var param = {collection : pass_array};
  chrome.runtime.sendMessage(param);
};
getHtml();

background.js

chrome.runtime.onMessage.addListener(
  function(arg, sender, sendResponse) {
    var args=arg.collection;
    for (i in args){
    var img_url=args[i];
    try{
     saveas=img_url.replace(/[^a-zA-Z0-9]/g,'-');
    }
    catch (problem){
    }

     chrome.downloads.download({
     url: img_url,
     filename: saveas,
    saveAs: false
    });
   }
});

  function sendResponse(){
  }

backgroundpage.html

<script src="background.js"></script>
Rico
  • 358
  • 2
  • 11
  • 1
    pretty lame but it demonstrates the chrome.downloads.download thingy – Rico Mar 24 '17 at 10:21
  • 1
    does not answer the question – Zig Mandel Mar 24 '17 at 12:29
  • 1
    i know, i am making the extension that answers the question, as of now, give me an hour or so – Rico Mar 24 '17 at 12:43
  • i already answered it. – Zig Mandel Mar 24 '17 at 12:45
  • 1
    yes, but i need the extension anyway, so i am making it ;) – Rico Mar 24 '17 at 12:47
  • @Rico, thank you for making an actual working solution and not only a comment! Will try it tomorrow! – EricC Mar 24 '17 at 17:03
  • the idea about stackoverflow is to provide enough information to answer the question, not receive a full sample. Show us what you tried already using a background page and messaging (per my answer) if you have further issues while implementing that solution. – Zig Mandel Mar 24 '17 at 20:59
  • yes, but the examples in documentation is not exhaustive, maybe i should write extensions and add them to the documentation ^_^ like just now i finished writing another extension to download some media files automatically, it feels so awesome – Rico Mar 24 '17 at 22:38
  • 1
    A suggestion to your answer. You might not need the backgroundpage.html to host background.js. Rather you can add background.js to your manifest.json under "background" : { "scripts" : ["background.js"] } – Soundararajan Aug 20 '19 at 05:27
  • With manifest version 3 you need: "background": { "service_worker": "background.js" } – g.a Jan 21 '23 at 21:34
4

you can't use many chrome. methods including .downloads from a content script. use a background or events page together with extension messaging, or directly from an extension popup.

Zig Mandel
  • 19,571
  • 5
  • 26
  • 36