先日作った「みんな大好き!くじ引きメーカー」。
このウェブアプリにくじの内容をダウンロードとアップロードができる機能を追加しようとしたら、iPhoneでフルスクリーンの時にダウンロードができないという事態に…。
今日はその解決方法を記録しとこうと思います。
●まずはダウンロードさせる関数
function downloadData(data) { var a = document.createElement('a'); a.download = 'kuji.txt'; a.href = 'data:application/octet-stream,'+encodeURIComponent(data); a.click(); }
軽く解説:
aタグを作って、download属性、href属性をセットして、強制的にクリックしてるだけです。
ちなみにdownload属性はHTML5から使えるみたいなので、IE9以前とかは使えないみたいですね。
あと、data:スキームも…。
●で、iPhoneフルスクリーンでの挙動
ボタンがピコんってなるだけで、無反応。
クリックイベントは来てるのに…。(.addEventListenerで確認)
●ちなみに、iPhone Safariでは
download属性は効いていないけれどダウンロードできました。
ファイル名がUnknown.txtになってしまう。(ここはあきらめた)
●で、最終どうしたか
downloadDataを呼び出すところで、iPhoneとそれ以外で分岐するようにして、
iPhoneの場合はdownload.htmlにジャンプさせて、download.html側でdownloadDataと同じ処理をするようにしましたとさ。
・分岐部分
var userAgent = window.navigator.userAgent.toLowerCase(); if (userAgent.indexOf('iphone') != -1) { var a = document.createElement('a'); a.href = './download.html?data='+encodeURIComponent(data); a.click(); } else { downloadData(data); }
軽く解説:
window.navigator.userAgentでユーザーエージェントが取ってこれるので、toLowerCaseで全て小文字にしてます。
小文字のユーザーエージェントにiphoneという文字列が入ってたら、download.htmlにジャンプ。
入っていなければdownloadDataを呼ぶようにしています。
・download.html
<html> <head> <script> var data = (window.location.search.substring(1)).replace(/^.*data=/, '').replace(/&.*$/, ''); var a = document.createElement('a'); a.download = 'kuji.txt'; a.href = 'data:application/octet-stream,'+data; a.click(); </script> </head> <body> </body> </html>
軽く解説:
window.location.searchは、URLの?で始まるクエリ部分が取ってこれます。
なので、正規表現で先頭からdata=までを削除して、&から最後まで削除します。
で、残ったのがダウンロードさせたいデータです。
あとはdownloadData関数と同じです。
ちなみに、dataにはURLエンコードされた文字列が入っているので、encodeURIComponentは通しません。
◆まとめ
ファイル名がUnknow.txtになったり、別途Safariが起動したり、気に入らないところはあるものの、ひとまずダウンロード&アップロードができるようになったので、良しとすることにしました。
もっと良い方法があれば、だれか教えて欲しいなぁ・・・。