Как правило, все, что вам когда-либо понадобится, - это переносить некоторое состояние между этими двумя запросами. На самом деле есть действительно забавный способ сделать это, который не зависит от JavaScript (подумайте <noscript />).
Set-Cookie: name=value; Max-Age=120; Path=/redirect.html
Имея этот файл cookie, вы можете в следующем запросе к /redirect.html получить информацию об имени = значении, вы можете сохранить любую информацию в этой строке пары имя / значение, вплоть до 4 КБ данных (типичное ограничение для файлов cookie). Конечно, вы должны избегать этого и хранить вместо этого коды состояния и биты флага.
Получив этот запрос, вы в ответ отвечаете запросом на удаление этого кода состояния.
Set-Cookie: name=value; Max-Age=0; Path=/redirect.html
Мой HTTP немного ржавый. Я прошёл через RFC2109 и RFC2965, чтобы выяснить, насколько это действительно надежно, желательно, чтобы cookie отправлялся в оба конца ровно один раз, но это не представляется возможным, в том числе и сторонние файлы cookie. может быть проблемой для вас, если вы переезжаете в другой домен. Это все еще возможно, но не так безболезненно, как когда вы делаете что-то внутри своего домена.
Проблема здесь заключается в параллелизме, если опытный пользователь использует несколько вкладок и ему удается чередовать пару запросов, принадлежащих одному и тому же сеансу (это очень маловероятно, но не невозможно), это может привести к несоответствиям в вашем приложении.
Это способ <noscript /> выполнять обходы HTTP без бессмысленных URL и JavaScript
Я предоставляю этот код как основную идею: если этот код выполняется в контексте, с которым вы не знакомы, я думаю, вы сможете решить, что это за часть.
Идея заключается в том, что при перенаправлении вы вызываете 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;
}