c#HttpWebResponse头编码

我有以下问题。 我联系了一个我知道使用301重定向的地址。

使用HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl);loHttp.AllowAutoRedirect = false; 这样我就不会被重定向了。

现在我得到响应的标题以识别新的url。

使用loWebResponse.GetResponseHeader("Location");

问题是,由于此URL包含希腊字符,因此返回的字符串全部混乱(由于编码)。

完整图片代码:

 HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl); loHttp.ContentType = "application/x-www-form-urlencoded"; loHttp.Method = "GET"; Timeout = 10000; loHttp.AllowAutoRedirect = false; HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse(); string url= loWebResponse.Headers["Location"]; 

如果您使用默认行为( loHttp.AllowAutoRedirect = true )并且您的代码不起作用(您没有被重定向到新资源),则意味着服务器未正确编码Location标头。 重定向是否在浏览器中运行?

例如,如果重定向url为http://site/Μία_Σελίδα则Location标头必须类似于http://site/%CE%95%CE%BD%CE%B9%CE%B1%CE%AF%CE%BF_%CE%94%CE%B5%CE%


更新:

在进一步调查问题后,我开始怀疑HttpWebRequest有些奇怪 。 发送请求时,服务器发送以下响应:

 HTTP/1.1 301 Moved Permanently Date: Fri, 11 Dec 2009 17:01:04 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET Location: http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/ Content-Length: 112 Content-Type: text/html; Charset=UTF-8 Cache-control: private Connection: close Set-Cookie: BIGipServerpool_webserver_gr=1007732746.36895.0000; path=/  

我们可以看到Location头包含非url编码的希腊字符。 根据HTTP规范,我不太确定这是否有效。 我们可以肯定地说,网络浏览器正确地解释了它。

这是有趣的部分。 似乎HttpWebRequest不使用UTF-8编码来解析响应头,因为在分析Location头时它给出: http://www.site.com/buy/κινηÏή-ÏÏαθεÏή-ÏηλεÏÏνία/c/cn69569/http://www.site.com/buy/κινηÏή-ÏÏαθεÏή-ÏηλεÏÏνία/c/cn69569/ ,这当然是错误的,当它试图重定向到这个位置时,服务器会响应一个新的重定向,依此类推,直到达到最大重定向次数,并且exception是抛出。

在解析响应头时,我找不到任何方法来指定HttpWebRequest使用的编码。 如果我们手动使用TcpCLient ,它可以很好地工作:

 using (var client = new TcpClient()) { client.Connect("www.site.com", 80); using (var stream = client.GetStream()) { var writer = new StreamWriter(stream); writer.WriteLine("GET /default/defaultcatg.asp?catg=69569 HTTP/1.1"); writer.WriteLine("Host: www.site.com"); writer.WriteLine("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090805 Shiretoko/3.5.2"); writer.WriteLine("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); writer.WriteLine("Accept-Language: en-us,en;q=0.5"); writer.WriteLine("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7"); writer.WriteLine("Connection: close"); writer.WriteLine(string.Empty); writer.WriteLine(string.Empty); writer.WriteLine(string.Empty); writer.Flush(); var reader = new StreamReader(stream); var response = reader.ReadToEnd(); // When looking at the response it correctly reads // Location: http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/ } } 

所以我对这种行为感到很困惑。 有没有办法指定HttpWebRequest使用的正确编码? 也许应该设置一些请求标头?

作为一种解决方法,您可以尝试修改执行重定向的asp页面并对Location标头进行urlencode。 例如,当您在ASP.NET应用程序中执行Response.Redirect(location) ,该位置将自动进行html编码,并且任何非标准字符都将转换为其对应的实体。

例如,如果你这样做: Response.Redirect("http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/"); 在ASP.NET应用程序中, Location标头将设置为:

 http://www.site.com/buy/%ce%ba%ce%b9%ce%bd%ce%b7%cf%84%ce%ae-%cf%83%cf%84%ce%b1%ce%b8%ce%b5%cf%81%ce%ae-%cf%84%ce%b7%ce%bb%ce%b5%cf%86%cf%89%ce%bd%ce%af%ce%b1/c/cn69569 

似乎这不是经典ASP的情况。

我不希望返回字符串格式错误……您如何确定它是否格式错误? 该字符串应采用unfode格式,如utf-8,可以很容易地表示希腊字符串。

可能你只是没有希腊字体来代表字符串?

正如Darin Dimitrov所解释的那样,我认为标头编码是由HttpWebResponse类中的错误引起的。 我们遇到了同样的问题,我们想在标题中添加一个cookie(Set-Cookie),这个cookie将包含非Ascii字符。 在我们的特殊情况下,这将是挪威字母’Æ’,’Ø’和’Å’(大写和小写)。 我们无法弄清楚如何使HeaderEncoding工作,但我们找到了使用cookie的Base64编码的解决方法。 请注意,这只有在您控制客户端和服务器端时才有效 (或者您可以说服负责服务器端代码的人为您添加Base64编码…)

在服务器端:

 var cookieData = "This text contains Norwegian letters; ÆØÅæøå"; var cookieDataAsUtf8Bytes = System.Text.Encoding.UTF8.GetBytes(cookieData); var cookieDataAsUtf8Base64Encoded = Convert.ToBase64String(cookieDataAsUtf8Bytes); var cookie = new HttpCookie("MyCookie", cookieDataAsUtf8Base64Encoded); response.Cookies.Add(cookie); 

在客户端:

 var cookieDataAsUtf8Bytes = Convert.FromBase64String(cookieDataAsUtf8Base64Encoded); var cookieData = System.Text.Encoding.UTF8.GetString(cookieDataAsUtf8Bytes); 

请注意,客户端的cookieDataAsUtf8Base64Encoded是cookie的数据部分(即’MyCookie = [data]’,其中’MyCookie =’被剥离)。