Post Запросы не удаются, когда устанавливается
-
29-09-2019 - |
Вопрос
Рассмотрим следующий случай:
- Веб-сервер запущен приложение .Net с
<sessionState cookieless="AutoDetect" />
. - Клиент публикует данные для него, используя простой
HttpWebRequest
(нет печенья).
Этот, казалось бы, простой случай вызывает серьезную неудачу.
Поскольку .NET не может определить, если запрашивающий агент (HttpWebRequest
) Поддерживает файлы cookie, это реагирует на запрос на почту с найден 302, найден перенаправленным в то же место с:
- Печенье названа
AspxAutoDetectCookie
в ответ - параметр запроса по имени
AspxAutoDetectCookie
В направленном месте
Затем запрашивающий агент должен запросить новое местоположение, которое HttpWebRequest
делает. Когда .NET видит AspxAutoDetectCookie
В строке запроса она знает, что это повторный запрос, и он может определить, поддерживаются ли Cookies, видя, если файл cookie AspxAutoDetectCookie
находится в заголовках запроса.
Проблема в том, что большинство запрашивающих агентов (веб-браузеры, HttpWebRequest
) Относитесь к 302, найденным, как будто это 303, см. Другое, и сделайте повторную просьбу Получить, независимо от оригинального метода HTTP! Любые данные, отправленные в исходный почтовый запрос, не передаются.
Правильный ответ должен быть 307 временным перенаправлением, который не изменяет метод запроса. (Пост запрос на местоположение X перенаправляет к СООБЩЕНИЕ Запрос на местоположение Y.)
Есть ли способ изменить это поведение в .NET, поэтому после запросов не разрушается?
Решение
Единственное решение, которое я могу видеть на это, это добавить AspxAutoDetectCookie=1
Для всех постов запросов.
Таким образом, ASP.NET никогда не перенаправляет запрос, и мы можем дополнить вопрос 302 против 307 в целом. Если файлы cookie встроен в запрос, ASP.NET будет обнаруживать, что Cookies поддерживаются, и если файлы cookie не будут встроены, оно предположит, что они нет.
Другие советы
Есть ли какие-либо проблемы с использованием незабываемых = «UareEviceProfile»? Вы можете использовать его в качестве решения для работы.
Вы также видите проблему, если Cookiless = True. Вы действительно помогли мне. Я даже не мог выяснить, что вызывает этот вопрос, пока я не удалил строку, устанавливаю сеансетуэтатацию Cookilesss, чтобы верно из моей web.config, увидела проблему исправленной, googled моих результатов и нашел эту страницу. Вы помогли объяснить, почему удаление этой линии исправила проблему. Можете ли вы дать мне знать, если вы найдете решение, которое не связано с изменением того, как я использую состояние сеанса?
Я знаю, что нить старая, но, еще одно жизнеспособное решение для создания и модуля HTTP для фиксации http Post над незабываемым.
Вот один я использую
using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.SessionState;
using System.IO;
using System.Text;
namespace CustomModule
{
public sealed class CookielessPostFixModule : IHttpModule
{
public void Init (HttpApplication application)
{
application.EndRequest += new
EventHandler(this.Application_EndRequest);
}
private string ConstructPostRedirection(HttpRequest req,
HttpResponse res)
{
StringBuilder build = new StringBuilder();
build.Append(
"<html>\n<body>\n<form name='Redirect' method='post' action='");
build.Append(res.ApplyAppPathModifier(req.Url.PathAndQuery));
build.Append("' id='Redirect' >");
foreach (object obj in req.Form)
{
build.Append(string.Format(
"\n<input type='hidden' name='{0}' value = '{1}'>",
(string)obj,req.Form[(string)obj]));
}
build.Append(
"\n<noscript><h2>Object moved <input type='submit' value='here'></h2></noscript>");
build.Append(@"</form>"+
"<script language='javascript'>"+
"<!--"+
"document.Redirect.submit();"+
"// -->"+
"</script>");
build.Append("</body></html>");
return build.ToString();
}
private bool IsSessionAcquired
{
get
{
return (HttpContext.Current.Items["AspCookielessSession"]!=null &&
HttpContext.Current.Items["AspCookielessSession"].ToString().Length>0);
}
}
private string ConstructPathAndQuery(string[] segments)
{
StringBuilder build = new StringBuilder();
for (int i=0;i<segments.Length;i++)
{
if (!segments[i].StartsWith("(")
&& !segments[i].EndsWith(")"))
build.Append(segments[i]);
}
return build.ToString();
}
private bool IsCallingSelf(Uri referer,Uri newpage)
{
if(referer==null || newpage==null)
return false;
string refpathandquery = ConstructPathAndQuery(
referer.Segments);
return refpathandquery == newpage.PathAndQuery;
}
private bool ShouldRedirect
{
get
{
HttpRequest req = HttpContext.Current.Request;
return (!IsSessionAcquired
&& req.RequestType.ToUpper() == "POST"
&& !IsCallingSelf(req.UrlReferrer,req.Url));
}
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpRequest req = HttpContext.Current.Request;
HttpResponse res = HttpContext.Current.Response;
if (!ShouldRedirect) return;
res.ClearContent();
res.ClearHeaders();
res.Output.Flush();
char[] chr = ConstructPostRedirection(req,res).ToCharArray();
res.Write(chr,0,chr.Length);
}
public void Dispose()
{}
}
}