7

次のケースを検討してください。

  • Web サーバーが .NET アプリを実行しています<sessionState cookieless="AutoDetect" />
  • クライアントは、単純なHttpWebRequest(Cookie なし) を使用してデータを送信しています。

この一見単純なケースは、大きな失敗を引き起こします。

.NET は、要求元のエージェント ( ) が Cookie をサポートしているかどうかを判断できないためHttpWebRequest、POST 要求に対して、次のように同じ場所への 302 Found リダイレクトで応答します。

  • AspxAutoDetectCookie応答で指定された Cookie
  • AspxAutoDetectCookie転送された場所で指定されたクエリ パラメータ

要求元のエージェントは、新しい場所を要求することになってHttpWebRequestいます。.NET は、クエリ文字列を確認すると、これが再要求であることを認識し、指定された Cookieが要求ヘッダーにあるAspxAutoDetectCookieかどうかを確認することで、Cookie がサポートされているかどうかを判断できます。AspxAutoDetectCookie

問題は、ほとんどのリクエスト エージェント (Web ブラウザHttpWebRequest) が 302 Found を 303 See Other であるかのように扱い、元の HTTP メソッドに関係なく、再リクエストを GET にすることです! 最初の POST 要求で送信されたデータは転送されません。

正しい応答は、要求メソッドを変更しない 307 一時リダイレクトである必要があります。(場所 X への POST 要求は、場所 Y へのPOST要求にリダイレクトされます。)

POST 要求が破棄されないように、.NET でこの動作を変更する方法はありますか?

3xx リダイレクトに関する情報

4

3 に答える 3

2

AspxAutoDetectCookie=1これに対する唯一の解決策は、すべての POST リクエストに追加することです。

このように、ASP.NET は要求をリダイレクトせず、302 対 307 の質問を完全に回避できます。Cookie が要求に埋め込まれている場合、ASP.NET は Cookie がサポートされていることを検出し、Cookie が埋め込まれていない場合はサポートされていないと見なします。

于 2010-08-24T22:09:10.247 に答える
0

スレッドが古いことは知っていますが、別の実行可能な解決策は、HTTP モジュールを作成して、Cookie を使用しない HTTP 投稿を修正することです。

これが私が使用するものです

            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()
                {}
              }
            }
于 2015-10-29T14:54:43.390 に答える
0

cookieless="UseDeviceProfile" の使用に問題はありますか? 回避策として使用できます。

于 2010-08-20T07:35:25.913 に答える