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のコマンドを実行。
※自己責任とは言えどもセキュリティ上微妙なやり方なのでサンプルは記載はしない。

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

2018-07-26
年賀状で「新春」とか書くけど・・・何故なんだろうと8月を目前にした今、疑問に思った。
2018-05-16
PHPで画像のヘッダ情報(?)の「Orientation」を元に画像回転させたい。
2018-03-05
Android Studioをインストール。エミュレータを軽くするトコまで終わらせたかったけど、挫折した。
2018-02-23
プッシュ通知について調べてた時にでてきたServiceWorker。そのServiceWorkerについてのメモ。
2017-12-13
jqueryで取得したDOM要素をオブジェクトじゃなくて、配列で受け取りたい