سؤال

النظر في الحالة التالية:

  • يقوم خادم الويب بتشغيل تطبيق .NET <sessionState cookieless="AutoDetect" />.
  • يقوم العميل بنشر البيانات إليها باستخدام بسيط HttpWebRequest (لا كعك محلاة).

هذه الحالة البسيطة على ما يبدو تسبب فشل كبير.

منذ .NET لا يمكن تحديد ما إذا كان الوكيل طلب (HttpWebRequest) يدعم ملفات تعريف الارتباط ، فهي تستجيب لطلب النشر مع إعادة توجيه 302 إلى نفس الموقع مع:

  • ملف تعريف الارتباط اسمه AspxAutoDetectCookie في الاستجابة
  • معلمة استعلام اسمها AspxAutoDetectCookie في الموقع المعاد توجيهه

من المفترض أن يطلب الوكيل الطالب الموقع الجديد ، الذي HttpWebRequest يفعل. عندما يرى .net AspxAutoDetectCookie في سلسلة الاستعلام ، يعرف أن هذا هو إعادة ترجع ، ويمكنه تحديد ما إذا كانت ملفات تعريف الارتباط مدعومة من خلال معرفة ما إذا كان ملف تعريف الارتباط اسمه AspxAutoDetectCookie هو في رؤوس الطلب.

المشكلة هي أن معظم الوكلاء المطلوبون (متصفحات الويب ، HttpWebRequest) علاج 302 وجدت كما لو كان 303 انظر الآخر وجعل إعادة الاسترداد الحصول ، بغض النظر عن طريقة HTTP الأصلية! لا يتم إعادة توجيه أي بيانات يتم إرسالها في طلب النشر الأولي.

يجب أن تكون الاستجابة الصحيحة هي إعادة توجيه مؤقت 307 ، والتي لا تغير طريقة الطلب. (طلب نشر إلى الموقع x يعيد توجيه إلى أ بريد طلب إلى الموقع Y.)

هل هناك أي طريقة لتغيير هذا السلوك في .NET حتى لا يتم تدمير طلبات البريد؟

معلومات عن إعادة توجيه 3xx

هل كانت مفيدة؟

المحلول

الحل الوحيد الذي يمكنني رؤيته في هذا هو الإلحاق AspxAutoDetectCookie=1 لجميع طلبات البريد.

وبهذه الطريقة ، لن يعيد ASP.NET أبدًا إعادة توجيه الطلب ويمكننا تفادي السؤال 302 مقابل 307 تمامًا. إذا تم تضمين ملفات تعريف الارتباط في الطلب ، فستكتشف ASP.NET أن ملفات تعريف الارتباط مدعومة ، وإذا لم يتم تضمين ملفات تعريف الارتباط ، فستفترض أنها ليست كذلك.

نصائح أخرى

هل هناك أي مشاكل في استخدام cookieless = "edeviceprofile"؟ يمكنك استخدامه كحل الحل البديل.

ترى أيضًا المشكلة إذا كان cookiless = صحيح. كنت حقا ساعدتني. لم أستطع حتى معرفة ما كان يتسبب في هذه المشكلة حتى أزلت خط السطر SessionState Cookilesss إلى True من الويب الخاص بي. لقد ساعدت في توضيح سبب إصلاح هذا الخط المشكلة. هل يمكنك إخباري إذا وجدت حلًا لا يتضمن تغيير طريقة استخدام حالة الجلسة؟

أعلم أن الخيط قديم ، لكن حل آخر قابل للتطبيق هو إنشاء وحدة HTTP لإصلاح منشور HTTP فوق Cookieless.

هنا واحد أستخدمه

            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