a要素のdownload属性を使えばchromeなどのモダンブラウザではコンテンツをダウンロードできるわけだが、IEはそうはいかない。例えば、下の画像をダウンロードする時、IE以外のモダンブラウザではこのように書けばダウンロードされる。
var a = document.createElement('a'); a.href = '/img/1.jpg'; a.download = 'neko'; document.body.appendChild(a); a.click(); document.body.removeChild(a);
IEではダウンロードが実行されずにそのままページ遷移してしまうのがわかる。そこで今日は、代替方法を書く。
その方法とは、xhrでrequestを送り、blobで返してもらいそれをダウンロードするという方法だ。下がそのコードである。
var xhr = new XMLHttpRequest(); xhr.open('GET', '/img/1.png'); xhr.responseType = 'blob'; xhr.onloadend = function() { if(xhr.status !== 200) return; window.navigator.msSaveBlob(xhr.response, 'neko'); } xhr.send();
IEにはnavigatorオブジェクトにmsSaveBlob(blob, fileName)というメソッドが用意されているようで、blobのダウンロードにはこれを使う。
もうすでにお気づきの方もいるかもしれないが、これは完全な代替方法にはなり得ない。なぜならxhrはクロスドメイン制限があるからだ。つまり、同一ドメインか、CORS(Cross-Origin Resource Sharing)に対応していないとダウンロードきない。そして、blobのやりとりはIE9以下は対応していない。しかし、使える機会はあると思うので、もしよかったら使ってほしい。
他にいい方法を知っているという方はぜひ教えてください><
どういう前提なのか、どういう制約があるかでちょっと変わってきますが、
古典的な手段として、サーバー側で
Content-disposition: attachment; filename=”1.png”
というのをHTTPヘッダにつけるという手段もあります。
これも同一ドメインで、サーバー側に手を入れられるという状況でないといけませんが。