js、ActiveXObject:ローカルにファイルを保存させたい

2017/01/11
諸々あると思うけど・・・諦めてほしい。

・・・とは言っても諦めるわけにはいかなかったので・・・やってみた。

ローカルに保存

まずは、「ローカルに保存」っていう表現がややこしいのが問題。

「ローカルに保存」といっても下記の3タイプある(他にもあるかもしれない)

  1. ユーザーの許可を得てダウンロード
  2. ユーザーの許可無しでtmpフォルダに保存
  3. ユーザーの許可無しで任意のフォルダに保存

※「許可を得て / 許可無し」っていうけど・・・正確には違う。

一つ目はただのブラウザからダウンロードっていう感じで問題無し。
二つ目はブラウザ指定アリで、tmpフォルダ限定でなら大丈夫。
三つ目はIE限定だけど、セキュリティ的にイヤがられるだろうし、将来的にはNGになりそう。

やりたいこと

今回やりたいことは・・・

ユーザーの意思は聞かずに任意のフォルダに保存したい。

別に悪いコトをしたいわけじゃなくて・・・面倒なプリンタのドライバを使わなくちゃいけないってのがあった。

そのプリンタのドライバはPCにあるファイルにアクセスしてくれるんだけど・・・アクセスしたいファイルはサーバにある。
だからアクセスしたいファイルをサーバからPCにコピーする必要があった。

それをユーザーにしてもらいたいけど、おそらく失敗・マニュアル外のコトをするユーザーが現れるのでユーザーじゃなくてサーバ側で処理したい。
VBで専用のアプリを作るってのも良いけど、Webアプリでする必要があった。

条件的には下記のようなコト。

  • 一連の流れは、ボタン一つですべて終わらせる
  • 対象はLAN内のみ。

処理的には下記のようなコト。

  1. ブラウザで特定のURLにアクセス
  2. ブラウザで特定のボタンをクリック
  3. サーバにあるファイルをPCにダウンロード
  4. ダウンロードしたファイルのPATHをプリンタのドライバに渡す

この際、ダウンロード先のPATHがユーザによって異なってくる。コレが困る。
ダウンロードしたPATHを取得できればコレでもいいんだけど・・・そういうのも無いみたいだし、そもそもダウンロード完了前に処理が走ると困るから、ダウンロードの監視もしなくちゃいけない。

ということで、ボタンをクリックする前にダウンロードを実行させておきたい。
流れ的には下記のような感じ(ファイルダウンロードの順番が異なる)

  1. ブラウザで特定のURLにアクセス
  2. サーバにあるファイルをPCにダウンロード
  3. ブラウザで特定のボタンをクリック
  4. ダウンロードしたファイルのPATHをプリンタのドライバに渡す

処理の草案

▼流れ

  1. 特定のWebページにアクセスされたらファイルをサーバからPCへダウンロード
  2. ブラウザで特定のボタンをクリック
  3. ダウンロードしたファイルのPATHをプリンタのドライバに渡す

▼条件等

  1. 利用可能なユーザは全員「LAN内+身内」なので、悪い人はいない
  2. ダウンロード先はWebページ内に記載:ユーザに保存先を変更させない
  3. ダウンロード先に同一ファイルがあったら上書き

ファイルの保存:実際の処理

少し回りくどいけどややこしくなるので順番にまとめておく。

ユーザーの許可を得てダウンロード

zipやpdfとかだったらリンクしたら勝手にダウンロードしてくれる。
画像やテキストファイルをダウンロードさせるならBlobを使ってダウンロード

var text = “テキストデータ”;
var blob = new Blob([text], {type: “text/plain”});
var fileName = “test.txt”;

if(window.navigator.msSaveBlob) {
  // IEなら独自関数
  window.navigator.msSaveBlob(blob, fileName);
}
else {
  // それ以外はaタグを利用してイベントを発火
  var a = document.createElement(“a”);
  a.href = URL.createObjectURL(blob);
  a.target = “_blank”;
  a.download = fileName;
  
  a.click();
  
  // firefoxだとdispatchEvent()する必要あるかも。
  // var e = document.createEvent(“MouseEvent”);
  // e.initEvent( “click”, false, true );
  // a.dispatchEvent( e );
  
  // オブジェクトURLをメモリから開放
  URL.revokeObjectURL();
}

※他にもFileAPIを使うとか色々とあるそうだ。

ユーザーの許可無しでtmpフォルダに保存

ブラウザ、保存先のPATHに条件があるけど、勝手にやってくれる。
ただ、IEの挙動が微妙だった。

参照:JavaScriptからローカルファイルを作成する方法まとめ:あらびき日記

ユーザーの許可無しで任意のフォルダに保存

IE限定で、ユーザーのPCにCMD(Winなら多分、大丈夫なはず)があるってことが前提。

やることは・・・ActiveXObject()の「Run()」でCMDのコマンドを実行。
※自己責任とは言えどもセキュリティ上微妙なやり方なのでサンプルは記載はしない。

新着(ニュース関連以外)

2017-06-27
MACにWin10をインストールしてみた:再挑戦。
2017-06-25
「簡単」っていうヤツらが多いけど・・・難しいぞ。
2017-06-06
FuelPHPのOILでtry・catchを使ったらエラーになった。
2017-04-11
動画をライトボックス風に表示したい・・・ライトボックス風って何? とりあえずbootstrapで対応したい。
2017-04-05
GitHubとかでzipをダウンロードすると・・・srcとdistと中身が似たようなのがよくあるので調べてみた。