要約
<a href="ダウンロードしたいファイルパス or blob" download="ダウンロードファイル名"><a>
というdownload
属性を使ったリンクは、
href
,
download
,
click
をJSで操作してもいいものの、a要素自体はdocument下に存在していなければならず、
JavaScript空間のみでcreateDocument
しただけのものでは一部ブラウザでダウンロードできない。
確認できたダウンロードできるブラウザは
- Vivaldi 2.2.1388.37
おそらく参考したコード記事からの情報によりChromeも可。
ダウンロードできないブラウザは
- Firefox 64
- IE 9
他のブラウザに関しては下記リンクからテストしてもらえればと思います。
多ブラウザ対応としては、ファイル内容をJSで作るにしてもダウンロード用のa要素を先にHTMLで書いておくか、JSでa要素を作ってもappendChildなどでDOMツリーに追加してやればいいんじゃないでしょうか。
発端
Togetterのツイートまとめをスクレイピングしてコマンドやブラウザから一発で取得する機能の開発 #ファイルダウンロード - Qiita
downloadText(e) {
const blob = new Blob([this.$store.state.text], {type: 'text/plain'})
const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = this.$store.state.text.split('\n')[0] + '.txt'
link.click()
},
(投降直前に気づきましたが、この処理はブラウザ依存のようです。
おそらくFirefox64とIE9ではファイルをダウンロードできません。
gif動画でダウンロードしているブラウザはVivaldiです。
理由は簡単なので気が向いたときか要望が出たときにでも直します)
これがブラウザによって動いたり動かなかったりする理由を考えたとき、
「HTML文章上にないものをクリックするというシチュエーションは謎だなあ」と考え、検証してみた。
ただ、結果ではダウンロードの場合に違いが現れ、たとえばクリックでアラートを出すような処理に関しては変数に対するclickでも動作した。
コード
<button id="document"> Document
</button>
<button id="js"> JavaScript
</button>
<a id="documentElement"></a>
<hr>
<button id="document2"> Document download
</button>
<button id="js2"> JavaScript download
</button>
<a id="documentElement2"></a>
function clickAlert() {
alert('click!')
}
const jsOnlyElement = document.createElement('a')
jsOnlyElement.addEventListener('click', clickAlert)
const documentElement = document.getElementById('documentElement')
documentElement.addEventListener('click', clickAlert)
document.getElementById('document').addEventListener('click', () => documentElement.click())
document.getElementById('js').addEventListener('click', () => jsOnlyElement.click())
/***************************/
function download(a, filename){
var blob = new Blob(['download!'], {type: "text/plain"})
a.href = URL.createObjectURL(blob);
a.target = '_blank';
a.download = filename + '.txt';
a.click();
}
const jsOnlyElement2 = document.createElement('a')
const documentElement2 = document.getElementById('documentElement2')
document.getElementById('document2').addEventListener('click', () => download(documentElement2, 'documentElement'))
document.getElementById('js2').addEventListener('click', () => download(jsOnlyElement2, 'jsOnlyElement'))
CodePenの匿名埋め込みは出来ないようなのでリンクで失礼。