完全な解決策はないようですが、私が試すいくつかのアプローチがあります。
1)iframe
実際のXHRの代わりにを使用して、データをサーバーにPOSTします。たとえば、非表示のiframeのは<form action="/something" target="myiframe">
どこですか。そうすれば、フォームは (メイン ウィンドウではなく) iframe を使用して、構成された URL にデータを送信します。ブラウザーがダウンロードをトリガーするように、サーバーは応答ヘッダーを(またはバイナリ データのその他の MIME タイプ) に設定する必要があります。それ以外の場合 (html が返された場合)、iframe の body innerHTML を取得して、UI でユーザーに表示することができます。XHR の代わりに iframe (または新しいウィンドウ) を使用することは最善のアイデアのようには思えませんが、このソリューションはこれまでのところ最も信頼性が高いようです (そして最高のブラウザー サポートを備えています)。myiframe
name
application/octet-stream
Ext.form.Basic docs ページの例を少し変更したものを次に示します。
Ext.create('Ext.form.Panel', {
title: 'Basic Form',
renderTo: Ext.getBody(),
width: 350,
// Any configuration items here will be automatically passed along to
// the Ext.form.Basic instance when it gets created.
// *THIS* makes the form use a standard submit mechanism, not XHR
/**/standardSubmit: true,
// URL to submit to
url: 'save-form.php',
items: [{
fieldLabel: 'Field',
xtype: 'textfield',
name: 'theField'
}],
buttons: [{
text: 'Submit',
handler: function() {
// The getForm() method returns the Ext.form.Basic instance:
var form = this.up('form').getForm();
if (form.isValid()) {
// Submit the Ajax request and handle the response
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
},
// You can put the name of your iframe here instead of _blank
// this parameter makes its way to Ext.form.Basic.doAction()
// and further leads to creation of StandardSubmit action instance
/**/ target: '_blank'
});
}
}
}]
});
ここには 2 つの重要なパラメーターがあります ( でマークされた行/**/
)。
standardSubmit: true
config をフォームに渡すと、XHR ではなく標準の送信が行われます。
target
フォームの送信アクションにパラメーターを渡します。この機能は文書化されていませんが、Ext.form.action.Submitソース コードで使用されていることがわかります ( Ext.form.Basic.submit()メソッドに渡すすべてのオプションは、最終的に Ext.form.action. * 実例。
サンプルコードでは、target: '_blank'
すぐに機能することを示すために入れました (新しいブラウザーウィンドウが作成されます)。後で iframe の名前に置き換えることができますが、最初にフォームがデータを通常の新しいウィンドウに送信する方法をテストしてから、iframe を作成して処理するロジックを開発することをお勧めします。自分で iframe 内の結果を処理する必要があると思いました。それほど難しいことではありません。iframe処理の例としてExt.data.Connection.upload()の実装を参照してください。
ExtJS は、実際iframe
にファイルのアップロードにすでにこの手法を使用しています。どのように機能するかについてはExt.data.ConnectionとExt.form.field.Field.isFileUpload()を参照してください。
2)ここで提案: HTML5/Javascript を使用してファイルを生成および保存します。
iframe の方法を使用したくない場合は、応答データからデータ URIを生成し、ダウンロードをトリガーするその URI に移動してみてください。
content = "Hello world!";
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
window.location.href = uriContent;
繰り返しますが、ここでは MIME タイプが不可欠です。これは私にとってはうまくいきましたが、ブラウザがデータ URI にサイズ制限を課していることに注意してください (256Kb が安全な賭けです)。
3)前述のスレッドの別の回答は、(放棄された?)w3仕様を実装するFileSaver.jsライブラリへのリンクです。使用方法とデモはこちら. [BlobBuilder] を使用して、いくつかの方法のいずれかを使用してダウンロードを初期化するためにさらに使用されるバイナリ データのブロブを生成します。このソリューションは機能しているように見えますが、非推奨の API を使用しているため、将来的に保証されない可能性があります。