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

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

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

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

JavaScript

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

Q&A

解決済

3回答

10126閲覧

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

masaya_ohashi

総合スコア9206

HTML5

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

JavaScript

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

0グッド

4クリップ

投稿2017/12/11 07:40

編集2017/12/12 00:45

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

###発生している問題・エラーメッセージ
そもそも検知できるかどうかすら、調べてもいまいち情報が出てこない。

###該当のソースコード
とくになし。

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

###補足情報(言語/FW/ツール等のバージョンなど)
【追記】全ブラウザ対応なので、特定のブラウザのみで使える方法等は不可でお願いします。

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

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

JavaScript

1export default class FileDownloader { 2 static download(url, method = 'GET', postData = null) { 3 let deferred = $.Deferred(function(dfd) { 4 var xhr = new XMLHttpRequest(); 5 xhr.open(method, url, true); 6 xhr.responseType = "arraybuffer"; 7 xhr.onload = function(e) { 8 if (xhr.readyState === 4) { 9 // 通信完了 10 switch (xhr.status) { 11 case 200: //成功 12 FileDownloader.downloadFromXhr(xhr); 13 dfd.resolve(); 14 break; 15 default: 16 dfd.reject(xhr.status + " " + xhr.statusText); 17 break; 18 } 19 } 20 }.bind(this); 21 xhr.send(); 22 }); 23 return deferred.promise(); 24 } 25 static downloadFromXhr(xhr, bom = false) { 26 let content = xhr.response; 27 let mimeType = xhr.getResponseHeader('content-type'); 28 let name = 'download'; 29 let contentDisposition = xhr.getResponseHeader('content-disposition'); 30 if (contentDisposition) { 31 let match = contentDisposition.match(/filename="(.*?)"/); 32 name = match[1]; 33 } 34 FileDownloader.downloadFromBinary(content, mimeType, name, bom); 35 } 36 static downloadFromBinary(content, mimeType, name, bom = false) { 37 // BOMは文字化け対策 38 if (bom) { 39 var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); 40 content = [bom, content]; 41 } 42 var blob = new Blob([content], { 43 type: mimeType 44 }); 45 46 var a = document.createElement('a'); 47 a.download = name; 48 a.target = '_blank'; 49 50 if (window.navigator.msSaveBlob) { 51 // for IE 52 window.navigator.msSaveBlob(blob, name) 53 } 54 else if (window.URL && window.URL.createObjectURL) { 55 // for Firefox 56 a.href = window.URL.createObjectURL(blob); 57 document.body.appendChild(a); 58 a.click(); 59 document.body.removeChild(a); 60 } 61 else if (window.webkitURL && window.webkitURL.createObject) { 62 // for Chrome 63 a.href = window.webkitURL.createObjectURL(blob); 64 a.click(); 65 } 66 else { 67 // for Safari 68 window.open('data:' + mimeType + ';base64,' + window.Base64.encode(content), '_blank'); 69 } 70 } 71} 72

投稿2018/01/11 07:08

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

□参考情報
WebExtensions API downloads

投稿2017/12/11 14:21

umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2017/12/12 00:44

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

0

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

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

think49さんの回答ですね。

投稿2017/12/11 08:05

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2017/12/11 08:28

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問