jqueryベースの単一ページWebアプリケーションがあります。AJAX呼び出しを介してRESTful Webサービスと通信します。
私は次のことを達成しようとしています:
- JSONデータを含むPOSTをREST URLに送信します。
- リクエストがJSONレスポンスを指定している場合、JSONが返されます。
- リクエストがPDF / XLS / etc応答を指定している場合、ダウンロード可能なバイナリが返されます。
現在1と2が機能しており、クライアントのjqueryアプリは、JSONデータに基づいてDOM要素を作成することにより、返されたデータをWebページに表示します。また、#3はWebサービスの観点からも機能しています。つまり、正しいJSONパラメーターを指定すると、バイナリファイルが作成されて返されます。しかし、クライアントのJavaScriptコードで#3を処理する最良の方法がわかりません。
このようなajax呼び出しからダウンロード可能なファイルを取得することは可能ですか?ブラウザでファイルをダウンロードして保存するにはどうすればよいですか?
$.ajax({
type: "POST",
url: "/services/test",
contentType: "application/json",
data: JSON.stringify({category: 42, sort: 3, type: "pdf"}),
dataType: "json",
success: function(json, status){
if (status != "success") {
log("Error loading data");
return;
}
log("Data loaded!");
},
error: function(result, status, err) {
log("Error loading data");
return;
}
});
サーバーは次のヘッダーで応答します。
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
別のアイデアは、PDFを生成してサーバーに保存し、ファイルへのURLを含むJSONを返すことです。次に、ajax成功ハンドラーで別の呼び出しを発行して、次のようなことを行います。
success: function(json,status) {
window.location.href = json.url;
}
しかし、それを行うには、サーバーに対して複数の呼び出しを行う必要があり、サーバーはダウンロード可能なファイルを作成してどこかに保存し、定期的にそのストレージ領域をクリーンアップする必要があります。
これを実現する簡単な方法がなければなりません。アイデア?
編集:$ .ajaxのドキュメントを確認した後、応答のdataTypeはの1つのみであることがわかります。そのxml, html, script, json, jsonp, text
ため、バイナリファイルをに埋め込んでいない限り、ajaxリクエストを使用してファイルを直接ダウンロードする方法はないと思います@VinayC回答で提案されているデータURIスキーム(これは私がやりたいことではありません)。
だから私は私の選択肢は次のとおりだと思います:
ajaxを使用せず、代わりにフォーム投稿を送信して、JSONデータをフォーム値に埋め込みます。おそらく隠しiframeなどをいじる必要があるでしょう。
ajaxを使用せず、代わりにJSONデータをクエリ文字列に変換して標準のGETリクエストを作成し、window.location.hrefをこのURLに設定します。ブラウザがアプリケーションURLから変更されないようにするために、クリックハンドラーでevent.preventDefault()を使用する必要があるかもしれません。
上記の他のアイデアを使用しますが、@ naikus回答からの提案で拡張されます。これがajax呼び出しによって呼び出されていることをWebサービスに通知するいくつかのパラメーターを指定してAJAX要求を送信します。Webサービスがajax呼び出しから呼び出された場合は、生成されたリソースへのURLとともにJSONを返すだけです。リソースが直接呼び出された場合は、実際のバイナリファイルを返します。
考えれば考えるほど、最後の選択肢が好きになります。このようにして、リクエストに関する情報(生成時間、ファイルのサイズ、エラーメッセージなど)を取得し、ダウンロードを開始する前にその情報に基づいて行動できます。欠点は、サーバー上の余分なファイル管理です。
これを達成する他の方法は?私が知っておくべきこれらの方法の長所/短所はありますか?
url = 'http://localhost/file.php?file='+ $('input').val(); window.open(url);
同じ結果を得る簡単な方法。ヘッダーをphpファイルに入れます。ajaxを送信したり、リクエストを取得したりする必要はありません