web-dev-qa-db-ja.com

JavaScriptを使用して画像を強制的にダウンロードする

Javascript/jQueryを使用してスクリプトを作成し、ブラウザに表示されないように画像をダウンロードする(ダウンロードダイアログを開く)方法があるかどうかを知りたい。

17
Nathan Campos

これにはサーバー側のスクリプトを使用する必要があります。 stackoverflowで検索

または、サーバーで、構成を使用してヘッダーを動的に変更できる場合があります。

Mod_headersを使用したApacheソリューション

ダウンロード可能なイメージをディレクトリに配置します。このディレクトリ内で、.htaccess次の内容のファイル:

SetEnvIf Request_URI "([^/]+\.jpg)$" REQUESTED_IMAGE_BASENAME=$1
SetEnvIf Request_URI "([^/]+\.png)$" REQUESTED_IMAGE_BASENAME=$1
Header set Content-Disposition "attachment; filename=\"%{REQUESTED_IMAGE_BASENAME}e\"" env=REQUESTED_IMAGE_BASENAME

テストリクエスト:

HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost

テスト応答:

HTTP/1.1 200 OK
Date: Sat, 23 Jul 2011 09:03:52 GMT
Server: Apache/2.2.17 (Win32)
Last-Modified: Thu, 23 Aug 2001 14:00:00 GMT
ETag: "26000000017df3-14752-38c32e813d800"
Accept-Ranges: bytes
Content-Length: 83794
Content-Disposition: attachment; filename="Water lilies.jpg"
Content-Type: image/jpeg

HTML5ソリューション

アンカーでHTML5 download属性を使用

<p>Example 1<br>
   <a href="http://dummyimage.com/600x400/000/fff.png" download>Download this image</a></p>

<p>Example 2<br>
   <a href="http://dummyimage.com/600x400/000/fff.png" download="alternate-filename.png"><img
       src="http://dummyimage.com/150x100/000/fff.png"></a></p>
35
Salman A

以下の制限付きで、画像のダウンロードを強制する純粋なJavaScriptの方法を思いつきました。

  1. HTML5を使用して、IE IE9以前のブラウザではまったく動作しません。
  2. In IE(偶数9))は、URLの長さの制限により、非常に小さな画像に制限されています。
  3. イメージ名(マシンに保存されたとき)は、コード内で決定できません。Chrome拡張子なしの「ダウンロード」であり、Firefoxでは、 「.part」拡張子-いずれにしても、ユーザーはファイルの名前を変更して使用可能にする必要があります。
  4. 同じドメイン内のイメージのみをダウンロードできます-同じOriginポリシー。

上記の制限(特に3番目)は多かれ少なかれこれを役に立たなくしますが、それでも、「コア」のアイデアisは機能し、将来のある時点でファイル名を決定できるようになります。はるかに便利になります。

コードは次のとおりです。

function DownloadImage(imageURL) {
    var oImage = document.getElementById(imageURL);
    var canvas = document.createElement("canvas");
    document.body.appendChild(canvas);
    if (typeof canvas.getContext == "undefined" || !canvas.getContext) {
        alert("browser does not support this action, sorry");
        return false;
    }

    try {
        var context = canvas.getContext("2d");
        var width = oImage.width;
        var height = oImage.height;
        canvas.width = width;
        canvas.height = height;
        canvas.style.width = width + "px";
        canvas.style.height = height + "px";
        context.drawImage(oImage, 0, 0, width, height);
        var rawImageData = canvas.toDataURL("image/png;base64");
        rawImageData = rawImageData.replace("image/png", "image/octet-stream");
        document.location.href = rawImageData;
        document.body.removeChild(canvas);
    }
    catch (err) {
        document.body.removeChild(canvas);
        alert("Sorry, can't download");
    }

    return true;
}

ご覧のとおり、画像をcanvasオブジェクトに描画し、画像の生のバイナリデータを取得し、image/octet-stream MIMEタイプを使用してブラウザの場所を変更することで強制的にダウンロードします。

使用例も同様に続きます。

HTML:

<image id="myimage" src="Penguins.jpg" />
<button type="btnDownload" rel="myimage">Download</button>

JavaScript:

window.onload = function() {
    var arrButtons = document.getElementsByTagName("button");
    for (var i = 0; i < arrButtons.length; i++) {
        var oButton = arrButtons[i];
        var sRelatedImage = oButton.getAttribute("rel");
        if (sRelatedImage && sRelatedImage.length > 0) {
            oButton.onclick = function() {
                HandleRelatedImage(this, sRelatedImage);
            }
        }
    }
};

function HandleRelatedImage(oButton, sRelatedImage) {
    var oImage = document.getElementById(sRelatedImage);
    if (!oImage) {
        alert("related image '" + sRelatedImage + "' does not exist");
        return false;
    }

    return DownloadImage(sRelatedImage);
}

これにより、ボタンのrel属性を画像IDに割り当てることで、ダウンロードボタンを既存のすべての画像に「添付」できます。コードは残りを実行し、実際のクリックイベントを添付します。

同じOriginポリシーにより、jsFiddleに実際の例を投稿することはできません。スクリプトを実行するために「サンドボックス」ドメインを使用しています。

14
Shadow Wizard

HTML5の「ダウンロード」属性を使用する簡単なソリューションを次に示します。

document.getElementById('download').click();
<a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a>
4
Triforcey

これは完全に可能です。画像をBase64としてエンコードし、window.open とともに data:image/jpg,Base64,...スタイルのURL。

0
buley

私はあなたがこのようなことを意味すると推測しています:

ブラウザでURLに移動します。URLは次のとおりです。 http://example.com/image.png

表示する代わりに、ブラウザは画像を保存するように求めますか?

Javascriptでこれを強制することはできず、ヘッダーを制御するためにサーバー側の言語が必要になることはかなり確信しています。また、その時点でもブラウザにダウンロードを強制することはできません。各ユーザーエージェントは、送信するヘッダーに応じて反応が異なります。

編集:ヘッダーがContent-Disposition: attachment;であることを覚えているようです

0
Anthony Sottile