代码之家  ›  专栏  ›  技术社区  ›  Daniel Chambers

HttpWebRequest仅在Internet Explorer中返回404s for 302s

  •  8
  • Daniel Chambers  · 技术社区  · 14 年前

    我有一个Silverlight(v3)应用程序 WebRequest 向Silverlight应用程序所在网站上的网页发出HTTP POST请求。这个HTTP请求返回一个302(重定向)到同一个网站上的另一个页面,这 HttpWebRequest 会自动跟随( according to the documentation ).

    发出请求的代码没有什么特别之处(它使用浏览器的HTTP堆栈,没有配置为使用备用的内置Silverlight HTTP堆栈):

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("{0}?name={1}&size={2}", _UploadUrl, Uri.EscapeUriString(Name), TotalBytes));
    request.Method = "POST";
    

    所有这些在Firefox和Chrome中都可以正常工作;Silverlight发出POST-HTTP请求,接收302响应,并自动执行指定重定向URL的GET-HTTP请求并将其返回给我(我知道这一点是因为我使用Fiddler监视HTTP请求的进行)。 但是,在InternetExplorer(v8)中,Silverlight执行POST HTTP请求,然后抛出一个带有404错误代码的WebException!

    使用Fiddler,我可以看到Silverlight/internetexplorer成功地返回了请求的302状态码,我假设在Silverlight中得到的404状态码(以及相关的WebException)是因为据我所知,由于限制,通过浏览器堆栈完成的HTTP请求只能返回200或404。真正的问题是 为什么InternetExplorer不像其他浏览器那样执行重定向

    提前感谢您的帮助!

    我不希望使用Silverlight客户端HTTP堆栈,因为据我所知,它发出的请求不包括作为浏览器会话一部分的Cookie,尤其包括ASP.NET需要附加到Silverlight控件发出的HTTP请求的身份验证cookie。

    编辑2:

    2 回复  |  直到 5 年前
        1
  •  3
  •   Jon Hanna    14 年前

    IE更接近于规范,在响应302的POST时,用户代理应该发送POST(尽管在没有用户确认的情况下不应该这样做)。

    另一方面,FF和Chrome是故意错误的,复制了用户代理在相当长一段时间前经常出错的方式(这个问题始于HTTP的早期)。

    因此,在HTTP/1.1中引入307是为了更清楚地说明应该使用相同的HTTP方法(即,在本例中,它应该是POST),而303始终意味着应该使用GET。

    因此 Response.Redirect 结果是302-不同的用户代理将以不同的方式处理,发送303。下面的代码就是这样做的(并且包含了一个有效的实体体,仅在规范的字母内)。有一个重载,因此您可以使用Uri或字符串调用它:

    private void SeeOther(Uri uri)
    {
      if(!uri.IsAbsoluteUri)
        uri = new Uri(Request.Url, uri);
      Response.StatusCode = 303;
      Response.AddHeader("Location", uri.AbsoluteUri);
      Response.ContentType = "text/uri-list";
      Response.Write(uri.AbsoluteUri);
      Context.ApplicationInstance.CompleteRequest();
    }
    private void SeeOther(string relUri)
    {
      SeeOther(new Uri(Request.Url, relUri));
    }