◆ navigator.msSaveOrOpenBlob で対応させる
◆ blob を取得するのが xhr なのでクロスドメインでダウンロードはできない

今更ですが IE11 って download 属性使えないんですね

ユーザが右クリックから保存すればいいだけではあるのですが動きを合わせたい人もいそうかなと思って polyfill を作ってみました

if(document.documentMode && navigator.msSaveOrOpenBlob){
window.addEventListener("click", function(eve){
var a = eve.target
if(!a.hasAttribute("download")) return
eve.preventDefault()
var filename = a.getAttribute("download")
var xhr = new XMLHttpRequest()
xhr.open("GET", a.href)
xhr.responseType = "blob"
xhr.send()
xhr.onload = function(){
navigator.msSaveOrOpenBlob(xhr.response, filename)
}
})
}

navigator.msSaveOrOpenBlob という関数がローカルに保存する関数です
IE と Edge にあります
強制的に保存じゃなくてよくある 「開きますか保存しますか」 の質問がでてくるやつです

download 属性がある場合に IE ならこれを使って保存させます

Edge では download 属性に対応してるので IE に限定するため document.documentMode も条件に入れてます


このコードをページロード時などに実行しておけば download 属性付きリンクをクリックすると IE でもダウンロードできます

ただし一つ注意があります
xhr を使う以上クロスドメインのダウンロードはできません
ダウンロードさせるファイルは自分のサイトのコンテンツのことがほとんどだと思いますが 外部のファイルをダウンロードさせたい場合には使えません

IE の xhr ではまった

IE の xhr で変に苦労させられました

var xhr = new XMLHttpRequest()
xhr.open("GET", "")

これがなぜか SyntaxError と言われます

open の第二引数に空文字があるのが原因で 空文字以外の文字列を渡すとエラーはでません
構文は間違ってないのに構文エラーなんて言われるからカッコ対応とか調べてしまって原因見つけるのに苦労しました

直接リテラルで "" にしてるからではなく変数で指定しても一緒です



もうひとつ

var xhr = new XMLHttpRequest()
xhr.responseType = "blob"
xhr.open("GET", "dummy")

これは

InvalidStateError


です

なにそれ……


open より先に responseType を設定すると発生します
先に open すると問題なく設定完了できます

Chrome などでは問題ないのに IE は 11 でもこういう変な仕様残ってるからイヤです