プラグインのドキュメントからの引用:jquery.form
XMLHttpRequestレベル2をサポートするブラウザーは、ファイルをシームレスにアップロードでき、アップロードが進むにつれて進行状況の更新を取得することもできます。古いブラウザの場合、XMLHttpRequestオブジェクトのレベル1の実装を使用してファイルをアップロードすることはできないため、iframeを含むフォールバックテクノロジが使用されます。これは一般的なフォールバック手法ですが、固有の制限があります。iframe要素は、フォームの送信操作のターゲットとして使用されます。これは、サーバーの応答がiframeに書き込まれることを意味します。これは、応答タイプがHTMLまたはXMLの場合は問題ありませんが、応答タイプがスクリプトまたはJSONの場合は同様に機能しません。どちらにも、HTMLマークアップで見つかった場合にエンティティ参照を使用して表現する必要のある文字が含まれていることがよくあります。
iframeモードを使用する場合のスクリプトおよびJSON応答の課題を説明するために、フォームプラグインでは、これらの応答をtextarea要素に埋め込むことができます。ファイルのアップロードなどと組み合わせて使用する場合は、これらの応答タイプに対してこれを行うことをお勧めします。ブラウザ。ただし、フォームにファイル入力がない場合、リクエストは通常のXHRを使用してフォームを送信することに注意してください(iframeではありません)。これにより、テキストエリアを使用する場合と使用しない場合を知るためにサーバーコードに負担がかかります。
つまり、フォームにファイル入力フィールドが含まれていて、このフォームをJSONを返すコントローラーアクションに送信する場合は、このJSONを<textarea>
タグでラップする必要があります。
したがって、応答は次のようにはなりません。
{ "redirectToUrl":"some url" }
次のようになります。
<textarea>{ "redirectToUrl":"some url" }</textarea>
これを実現するには、応答をこれらのタグでラップするカスタムアクション結果を使用できます。
public class TextareaJsonResult : JsonResult
{
public TextareaJsonResult(object data)
{
this.Data = data;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
bool shouldWrap = !context.HttpContext.Request.IsAjaxRequest();
if (shouldWrap)
{
response.Write("<textarea>");
}
base.ExecuteResult(context);
if (shouldWrap)
{
response.ContentType = "text/html";
response.Write("</textarea>");
}
}
}
次に、コントローラーアクションに次のカスタム結果を返してもらいます。
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
// ... some processing
var redirectToUrl = Url.Action(
"Create",
"Album",
new { url = url, isLocalFile = isLocalFile }
);
return new TextareaJsonResult(new { redirectToUrl = redirectToUrl });
}
明らかに、AJAX成功コールバックでは、テストしてこの違いを考慮する必要があります。typeof result
レガシーブラウザ(Internet Explorerなど)の場合は、手動で応答を解析します。リンク先のページのソースコードをご覧ください。
しかし、そうは言っても、成功コールバックでは、サーバーから返されたJSON応答に含まれるコントローラーアクションにリダイレクトしていることがわかります。ここに私の質問があります:リダイレクトする場合、そもそもAJAXを使用する意味は何ですか?コントローラーアクションへの標準フォームポストを使用して、コントローラーアクションに直接リダイレクトを実行させてみませんか?同じページにとどまりたい場合は、AJAXを使用する必要があります。