質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.05%

  • JavaScript

    13297questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML5

    3274questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

ファイルをダウンロードするaタグの、ダウンロード開始・終了を検知するスマートな方法を探しています

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 293

masaya_ohashi

score 8654

前提・実現したいこと

ファイルがダウンロードされるurlを持ったaタグがクリックされた際の、ファイルダウンロード開始のタイミング、完了のタイミングが検知したい。

発生している問題・エラーメッセージ

そもそも検知できるかどうかすら、調べてもいまいち情報が出てこない。

該当のソースコード

とくになし。

試したこと

clickイベントは分かるが、ダウンロード完了をどうやったら検知できるかがわからない。

補足情報(言語/FW/ツール等のバージョンなど)

【追記】全ブラウザ対応なので、特定のブラウザのみで使える方法等は不可でお願いします。

ajax等でバイナリを取ってくる→window.URL.createObjectURLで無理やりダウンロードのような動作をさせる、という方法や、クッキーを使ったテクニックもありますが、もっとスマートにやる方法がないかを模索しています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

check解決した方法

+1

とりあえずの解決として、aタグをクリックした際にJavaScriptでデータをダウンロードさせる方法を取りました。ES6用のクラスとしてFileDownloaderというクラスを作ってみました。これでしばらく運用しようと思っています。まだ意見は募集しておりますので、こっちのほうが楽だぞ!という意見がありましたらぜひ投稿お願いいたします。

export default class FileDownloader {
    static download(url, method = 'GET', postData = null) {
        let deferred = $.Deferred(function(dfd) {
            var xhr = new XMLHttpRequest();
            xhr.open(method, url, true);
            xhr.responseType = "arraybuffer";
            xhr.onload = function(e) {
                if (xhr.readyState === 4) {
                    // 通信完了
                    switch (xhr.status) {
                        case 200: //成功
                            FileDownloader.downloadFromXhr(xhr);
                            dfd.resolve();
                            break;
                        default:
                            dfd.reject(xhr.status + " " + xhr.statusText);
                            break;
                    }
                }
            }.bind(this);
            xhr.send();
        });
        return deferred.promise();
    }
    static downloadFromXhr(xhr, bom = false) {
        let content = xhr.response;
        let mimeType = xhr.getResponseHeader('content-type');
        let name = 'download';
        let contentDisposition = xhr.getResponseHeader('content-disposition');
        if (contentDisposition) {
            let match = contentDisposition.match(/filename="(.*?)"/);
            name = match[1];
        }
        FileDownloader.downloadFromBinary(content, mimeType, name, bom);
    }
    static downloadFromBinary(content, mimeType, name, bom = false) {
        // BOMは文字化け対策
        if (bom) {
            var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
            content = [bom, content];
        }
        var blob = new Blob([content], {
            type: mimeType
        });

        var a = document.createElement('a');
        a.download = name;
        a.target = '_blank';

        if (window.navigator.msSaveBlob) {
            // for IE
            window.navigator.msSaveBlob(blob, name)
        }
        else if (window.URL && window.URL.createObjectURL) {
            // for Firefox
            a.href = window.URL.createObjectURL(blob);
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
        }
        else if (window.webkitURL && window.webkitURL.createObject) {
            // for Chrome
            a.href = window.webkitURL.createObjectURL(blob);
            a.click();
        }
        else {
            // for Safari
            window.open('data:' + mimeType + ';base64,' + window.Base64.encode(content), '_blank');
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

調べてみましたが、クッキーを使った方法がほとんどですね。ただ、teratailの中にも同じような質問がありましたので、参考にしてみてはどうでしょうか?

非同期実行される関数のコールバック

think49さんの回答ですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/11 17:28

    やっぱりそうですよね…私の調べ方が甘くて情報が出てこないというパターンを期待しているのですが…もう少し回答を待ってみます。

    キャンセル

+1

ブラウザ拡張の機能を使用してもよいのでしたら、chrome.downloads APIが使用できるかと。
chrome.downloads.onCreated イベント
chrome.downloads.search イベント

□参考情報
WebExtensions API downloads

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/12 09:44

    なるほどー、Extensionという発想はなかったです。しかし全ブラウザ対応が必要なので今回はこの方法は取れないです…質問文に追記しておきます。ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.05%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    13297questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML5

    3274questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。