9

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

使用HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl); andloHttp.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"];
4

3 回答 3

6

如果您让默认行为 ( 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=/


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

正如我们所见,Location标题包含未经过 url 编码的希腊字符。根据HTTP 规范,我不太确定这是否有效。我们可以肯定地说,网络浏览器可以正确解释它。

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

我找不到任何方法来指定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 并非如此。

于 2009-12-11T16:20:07.627 回答
1

我不希望返回字符串格式错误...您如何确定它格式错误?该字符串应采用 UTF-8 之类的 unicode 格式,可以轻松表示希腊字符串。

可能是您没有希腊字体来表示字符串?

于 2009-12-11T15:48:56.130 回答
1

正如 Darin Dimitrov 解释的那样,我认为标头编码是由 HttpWebResponse 类中的错误引起的。我们遇到了同样的问题,我们想在标题中添加一个 cookie(Set-Cookie),而这个 cookie 将包含非 Ascii 字符。在我们的特殊情况下,这将是挪威字母“Æ”、“Ø”和“Å”(大写和小写)。我们不知道如何让cookieHeaderEncoding工作,但我们找到了使用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=”被删除)。

于 2011-09-05T07:15:59.463 回答