Вопрос

Рассмотрим следующий случай:

  • Веб-сервер запущен приложение .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, поэтому после запросов не разрушается?

Информация о перенаправлении 3xx

Это было полезно?

Решение

Единственное решение, которое я могу видеть на это, это добавить 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()
                {}
              }
            }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top