5

Hi i am downloading selected links using chrome extension but I can't set downloads location. All the urls downloaded to default location of chrome. i know we can't do it because of security reason. can we prompt directory chooser dialog in chrome extension popup from here user can select the Download path.Need any information from my side let me know.

Is this possible at all? Any suggestions on how to go about it?

Thanks in advance My code

function downloadFile(url, onSuccess,arrayOfUrl,zip) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = "blob";
    xhr.onreadystatechange = function () {

        if (xhr.readyState == 4) {
            if (onSuccess)
            {
            onDownloadComplete(xhr.response, arrayOfUrl,zip)
             }
}
}
xhr.send("null");
}
function onDownloadComplete(blobData,urls,zip ){
    if (count < urls.length) {
        blobToBase64(blobData, function(binaryData){
                var fileName = urls[count].substring(urls[count].lastIndexOf('/')+1);
                 zip.file(fileName+".docx", binaryData, {base64: true}); 
                if (count < urls.length -1){
                    count++;
                    downloadFile(urls[count], onDownloadComplete, urls,zip);

                }
                else {

                    var content = zip.generate();

                     var zipName = 'download.zip';
                var a = document.createElement('a'); 
                a.href = "data:application/zip;base64," + content;
                a.download = zipName;
                a.click();
                  count = 0;

                }
            });
    }
}

popup.js

function onDownloadComplete(blobData,urls,zip ){


    if (count < urls.length) {
        blobToBase64(blobData, function(binaryData){
                // add downloaded file to zip:
                var fileName = urls[count].substring(urls[count].lastIndexOf('/')+1);
               // zip.file(fileName, binaryData, {base64: true});
                 zip.file(fileName+".docx", binaryData, {base64: true}); //file"+count+".docx"
                if (count < urls.length -1){
                    count++;
                    downloadFile(urls[count], onDownloadComplete, urls,zip);

                }
                else {
                chrome.runtime.getBackgroundPage(function () {
            zipAndSaveFiles(zip);});



            }

            });
    }
}

**background.js**

function zipAndSaveFiles(zip)
{
    var content = zip.generate(zip);
                   var zipName = 'download.zip';
                   var dataURL = 'data:application/zip;base64,' + content;
                   chrome.downloads.download({
                   url:      dataURL,
                   filename: zipName,
                    saveAs:   true
                    });
}
Arvind Anandala
  • 539
  • 2
  • 7
  • 15
  • 1
    Have you looked at **[`chrome.downloads.download()`](http://developer.chrome.com/extensions/downloads.html#method-download)** ? – gkalpak Jan 08 '14 at 06:37
  • Yes i know that, But i want to give some more information regarding this. I am building a zip file with all downloadable files using JsZip library. I need to prompt a directory chooser path in extension popup , such that where to save the zip file. Is it possbile? provide any links and sample code to complete this.and see my updated question with my code – Arvind Anandala Jan 08 '14 at 07:01
  • @ExpertSystem is my updated code give you any idea? let me know if you need further information.Using FileSystem API can we do this Because this is urgent – Arvind Anandala Jan 08 '14 at 09:19

1 Answers1

4

Since you are generating and downloading just one ZIP file, you can use the chrome.downloads.download() method. E.g.:

var content = zip.generate();
var zipName = 'download.zip';
var dataURL = 'data:application/zip;base64,' + content;
chrome.downloads.download({
    url:      dataURL,
    filename: zipName,
    saveAs:   true
});
count = 0;

If you omit the display of a SaveAs dialog, then you can only specify a file name that is inside the user-defined download folder or in a subfolder of it.


Regarding the issue with the popup (see comment below): You should call the function from your background-page, not the popup. E.g. you could use chrome.runtime.sendMessage/onMessage to pass a message to your background-page:

In background.js:

...
function zipAndSaveFiles(...) { ... }
chrome.runtime.onMessage.addListener(function(msg, sender) {
    if ((msg.action === 'zipAndSave')
            && (msg.params !== undefined)) {
        zipAndSaveFiles(msg.params);
    }
});

In popup.js:

...
chrome.runtime.sendMessage({
    action: 'zipAndSave',
    params: ['url1', 'url2', 'url3']
});
gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • Thanks for your reply."SaveAs :true" is always asking to select the save directory(Where we want to save the file).Can we make it to ask first time only when click on download button. I don't want to ask always. – Arvind Anandala Jan 08 '14 at 11:30
  • One more thing i observed here when click on download button in extension popup, saveAs popup is coming and immediately closes before i select the destination(where i want to save file). Any idea? why it is happening.How to solve this? – Arvind Anandala Jan 08 '14 at 12:22
  • Hm...actually I could not reproduce the problem, so it is not what I thought. Did the updated code above solve the problem ? It might help to see the actual code in `popup.js`. – gkalpak Jan 08 '14 at 12:33
  • Thanks for your replay again.I tried the code as you told But no luck...Same thing is happening, SaveAs popup is closing before i select the destination path, Extension popup also closing same time. See my updated code(background.js and popup.js). Thank you – – Arvind Anandala Jan 08 '14 at 13:21
  • Please, try my updated answer (I still can't reproduce the problem though - maybe it is OS-specific). – gkalpak Jan 08 '14 at 13:28
  • I am using Mac OS 10.8.5. i checked with Windows its working great...But in mac it is giving above error – Arvind Anandala Jan 08 '14 at 13:50
  • Have you tried the message passing solution ? If it doesn't work, do you get any errors in the console (check both the popup's console log and that of the background-page) ? BTW, it would be better to move the whole zipping logic to the background-page, not just pass it the final `zip` object. – gkalpak Jan 08 '14 at 13:59
  • Sorry buddy, I am not able to do with the updated code also. But I think the issue can be tackled if i am able to bring the save as dialog to the browser window, rather than on extension window. I m trying "chrome.windows.getLastFocused". Do you think this can be helpful? If so, then please help me with the code. Thanks for so much help btw. :) – Arvind Anandala Jan 08 '14 at 14:51
  • No, this won't work as only the popup and the background-page (or other views of the extension) have access to the `downloads` API. I don't see any reason why the message passing wouldn't work. Does it open and immediately closes again ? (Unfortunately, I don't have access to a Mac in order to reproduce the problem. Maybe posting a new question - specific to `downloads` API's SaveAs dialog on OSX might yield some helpful answers.) – gkalpak Jan 08 '14 at 14:57
  • NP :) BTW, since this answer solved your original problem (that of prompting the user for a download destination), you might want to mark it as "accepted". – gkalpak Jan 09 '14 at 08:44
  • Thanks for your detailed answer and i am marking it as accepted Answer.Thank you very much once again – Arvind Anandala Jan 09 '14 at 14:05