Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Chrome拡張機能:複数ファイルをZIPにまとめてダウンロードする

More than 1 year has passed since last update.

はじめに

やりたいこと

サムネイル表示されている画像ファイルをZIPにまとめてダウンロードする。

制限事項

たとえChrome拡張機能がダウンロードしたものでも、ローカルのファイルにはアクセスできない。

ゆえに、メモリ上の画像データからZIPデータを作成し、それをダウンロードする。ZIPの作成にはJSZipを使用した。

手順1:画像ファイルのパスを探す

サムネイルからリンクをたどってオリジナル画像のURLを取得する。

その際、画像ファイルが置かれているドメインを確認し、manifest.jsonのpermissionsに追加する。(Flickrの場合は、「https://c1.staticflickr.com/」など。)ワイルドカードが使えないので、連番が降られている場合はすべての番号を追加する必要がある。

手順2:画像ファイルのダウンロード

XMLHttpRequestのresponseTypearraybufferを指定することで、画像ファイルをバイナリデータとして取得できる。

background.js
const DownloadArraybuffer = (url) => {
  const p = new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'arraybuffer';
    xhr.addEventListener('loadend', () => {resolve(xhr.response);});
    xhr.send();
  });

  return p;
}

手順3:ZIPデータを作成する

JSZipオブジェクトを作成し、fileメソッドでダウンロードした画像データを追加する。最後にgenerateAsyncメソッドを実行すればZIPデータが作成される。

background.js
const ZipGenerateAsync = (zip) => {
  return new Promise((resolve, reject) => {
    zip.generateAsync({type: "blob"}).then(resolve);
  });
};

const CreateZipBlob = async (urlList) => {
  const zip = new JSZip();

  for(let i = 0; i < urlList.length; i++) {
    const imageFile = await DownloadArraybuffer(urlList[i]);
    const fileName = i + '.jpg'

    zip.file(fileName, imageFile, {binary: true});
  }

  return await ZipGenerateAsync(zip);
}

手順4:ZIPデータをダウンロードする

createObjectURLの引数にバイナリデータを渡すと、ダウンロードするためのURLを発行できる。ダウンロード後はrevokeObjectURLでURLを破棄し、バイナリデータを開放する。

background.js
const DownloadFile = (url, filename) => {
  return new Promise(resolve => {
    chrome.downloads.download({url: url, filename: filename}, downloadId => {
      resolve(downloadId);
    });
  });
};

const Download = async () => {
  ...
  const zipBlob = await CreateZipBlob(urlList);
  const zipUrl = window.URL.createObjectURL(blob);
  const zipName = 'aaa.zip'

  await DownloadFile(zipUrl, zipName);
  window.URL.revokeObjectURL(zipUrl);
}
flasksrw
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away