我有一个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请求)。 但是,在Internet Explorer(v8)中,Silverlight执行POST HTTP请求,然后抛出带有404错误代码的WebException!
使用Fiddler,我可以看到Silverlight / Internet Explorer成功返回了请求的302状态代码,我假设我在Silverlight中获得的404状态代码(以及相关的WebException)是因为据我所知由于限制,通过浏览器堆栈完成的HTTP请求只能返回200或404。真正的问题是为什么Internet Explorer不像其他浏览器那样遵循重定向?
提前感谢您的帮助!
编辑:我不想使用Silverlight客户端HTTP堆栈,因为根据我的知识,它发出的请求不包含作为浏览器会话一部分的cookie,主要包括ASP.NET我需要附加到Silverlight控件发出的HTTP请求的身份验证cookie。
编辑2:我发现Internet Explorer仅在您执行POST请求时出现此行为。 GET请求成功重定向。考虑到现在有多少网站采用Post-Redirect-Get风格做事情,这似乎是非常不好的行为。
我创建了一个简单的demo VS2008 solution,如果它有帮助,它会表现出这种奇怪的行为。它包含一个基本的ASP.NET MVC 1项目和一个Silverlight 3项目。导航到网站上的SilverlightControlTestPage.html页面以查看实际问题。
答案 0 :(得分:3)
IE更接近规范,因为在响应POST的302时,用户代理应该发送POST(尽管如果没有用户确认,它不应该这样做)。
另一方面,FF和Chrome故意错误地复制了很久以前用户代理经常出错的方式(问题始于HTTP的早期阶段)。
出于这个原因,在HTTP / 1.1中引入了307更清楚,应该使用相同的HTTP方法(即在这种情况下,它应该是一个POST),而303总是意味着应该使用GET。
因此,不是执行导致302的Response.Redirect
- 不同的用户代理将以不同的方式处理,而是发送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));
}
答案 1 :(得分:0)
我相信这是Internet Explorer 7中的功能更改,他们将预期的200响应更改为302,告知IE重定向。我知道这个问题并没有顺利解决。一段时间提出了类似的问题here。
Change in behavior with Internet Explorer 7 and later in regard to CONNECT requests