通常、必要なのは、これら2つのリクエスト間で状態を運ぶことだけです。JavaScriptに依存しない、これを行うには本当にファンキーな方法があります(<noscript />を考えてください)。
Set-Cookie: name=value; Max-Age=120; Path=/redirect.html
そこにそのCookieがある場合、/ redirect.htmlへの次のリクエストでname = value情報を取得できます。この名前と値のペアの文字列には、最大4Kのデータ(通常のCookieの制限)まで、あらゆる種類の情報を格納できます。もちろん、これを避け、代わりにステータスコードとフラグビットを保存する必要があります。
このリクエストを受け取ると、代わりにそのステータスコードの削除リクエストで応答します。
Set-Cookie: name=value; Max-Age=0; Path=/redirect.html
私のHTTPは少し錆びています。RFC2109とRFC2965を使用して、これが実際にどの程度信頼できるかを把握してきました。できれば、Cookieを1回だけ正確に往復させたいのですが、それが可能ではないようです。サードパーティのCookie別のドメインに移動する場合は、問題になる可能性があります。これはまだ可能ですが、自分のドメイン内で何かをしているときほど痛みはありません。
ここでの問題は同時実行性です。パワーユーザーが複数のタブを使用していて、同じセッションに属する2、3のリクエストを交互にインターリーブすると(これは非常にまれですが、不可能ではありません)、アプリケーションの不整合につながる可能性があります。
これは、無意味なURLとJavaScriptなしでHTTPラウンドトリップを行う<noscript />の方法です
私はこのコードを概念の教授として提供します:このコードがあなたが慣れていないコンテキストで実行される場合、私はあなたがどの部分が何であるかを理解できると思います。
リダイレクトするときに何らかの状態でRelocateを呼び出し、再配置したURLがGetStateを呼び出してデータ(ある場合)を取得するという考え方です。
const string StateCookieName = "state";
static int StateCookieID;
protected void Relocate(string url, object state)
{
var key = "__" + StateCookieName + Interlocked
.Add(ref StateCookieID, 1).ToInvariantString();
var absoluteExpiration = DateTime.Now
.Add(new TimeSpan(120 * TimeSpan.TicksPerSecond));
Context.Cache.Insert(key, state, null, absoluteExpiration,
Cache.NoSlidingExpiration);
var path = Context.Response.ApplyAppPathModifier(url);
Context.Response.Cookies
.Add(new HttpCookie(StateCookieName, key)
{
Path = path,
Expires = absoluteExpiration
});
Context.Response.Redirect(path, false);
}
protected TData GetState<TData>()
where TData : class
{
var cookie = Context.Request.Cookies[StateCookieName];
if (cookie != null)
{
var key = cookie.Value;
if (key.IsNonEmpty())
{
var obj = Context.Cache.Remove(key);
Context.Response.Cookies
.Add(new HttpCookie(StateCookieName)
{
Path = cookie.Path,
Expires = new DateTime(1970, 1, 1)
});
return obj as TData;
}
}
return null;
}