7

Hãy xem xét các trường hợp sau đây:yêu cầu POST thất bại khi <sessionState cookie = "AutoDetect" /> được thiết lập

  • Một máy chủ web đang chạy một ứng dụng .NET với <sessionState cookieless="AutoDetect" />.
  • Khách hàng đang đăng dữ liệu lên đó bằng cách sử dụng đơn giản HttpWebRequest (không có cookie).

Trường hợp dường như đơn giản này gây ra lỗi lớn.

Kể từ NET không thể xác định nếu các đại lý yêu cầu (HttpWebRequest) hỗ trợ các tập tin cookie, nó đáp ứng các yêu cầu POST với 302 Tìm thấy chuyển hướng đến cùng một vị trí với:

  • cookie có tên AspxAutoDetectCookie trong phản ứng
  • một tham số truy vấn tên AspxAutoDetectCookie ở vị trí chuyển tiếp

các đại lý yêu cầu sau đó được cho là yêu cầu vị trí mới, mà HttpWebRequest làm. Khi .NET thấy AspxAutoDetectCookie trong chuỗi truy vấn, nó biết đây là yêu cầu lại và có thể xác định xem cookie có được hỗ trợ hay không bằng cách xem cookie có tên là AspxAutoDetectCookie nằm trong tiêu đề yêu cầu hay không.

Vấn đề là hầu hết các đại lý yêu cầu (trình duyệt web, HttpWebRequest) xử lý 302 Tìm thấy như thể nó là 303 Xem Khác và yêu cầu lại GET, bất kể phương thức HTTP gốc! Mọi dữ liệu được gửi trong yêu cầu POST ban đầu sẽ không được chuyển tiếp.

Câu trả lời chính xác phải là Chuyển hướng tạm thời 307, không thay đổi phương thức yêu cầu. (Yêu cầu POST đối với vị trí X chuyển hướng đến một số POST yêu cầu đến vị trí Y.)

Có cách nào để thay đổi hành vi này trong .NET nên yêu cầu POST không bị hủy?

Information on 3xx redirection

Trả lời

1

Giải pháp duy nhất tôi có thể xem là thêm chi tiết AspxAutoDetectCookie=1 vào tất cả các yêu cầu POST.

Bằng cách này, ASP.NET sẽ không bao giờ chuyển hướng yêu cầu và chúng tôi có thể né tránh câu hỏi 302 và 307 hoàn toàn. Nếu cookie được nhúng trong yêu cầu, ASP.NET sẽ phát hiện rằng cookie được hỗ trợ và nếu không có cookie nào được nhúng, nó sẽ cho rằng chúng không được.

+0

Không hoạt động ở đây ít nhất. Vẫn giảm dữ liệu bài đăng. – Karlth

+0

Nó hoạt động nếu chúng ta gắn thêm tiêu đề: 'Cookie: AspxAutoDetectCookie = 1'. – Artyom

0

Có bất kỳ vấn đề trong việc sử dụng cookie = "UseDeviceProfile"? Bạn có thể sử dụng nó như một giải pháp workaround.

+0

Thật không may, tôi không thể sử dụng thiết lập đó. Nó phải làm việc với "AutoDetect". – Anton

0

Bạn cũng thấy vấn đề nếu cookiless = true. Bạn thực sự đã giúp tôi. Tôi thậm chí không thể tìm ra những gì đã gây ra vấn đề này cho đến khi tôi gỡ bỏ các dòng thiết lập sessionil cookilesss để đúng từ web.config của tôi, thấy vấn đề cố định, googled kết quả của tôi và tìm thấy trang này. Bạn đã giúp giải thích tại sao việc xóa dòng này đã khắc phục được sự cố. Bạn có thể cho tôi biết nếu bạn tìm thấy giải pháp không liên quan đến việc thay đổi cách tôi sử dụng trạng thái phiên không?

0

Tôi biết chủ đề cũ nhưng một giải pháp khả thi khác là tạo và Mô-đun HTTP để sửa lỗi http đăng trên cookieless.

Dưới đây là một trong tôi sử dụng

  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() 
       {} 
       } 
      } 
Các vấn đề liên quan