9

次の問題があります。301 リダイレクトを使用していることがわかっているアドレスに連絡します。

HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl); andを使用し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"];
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 仕様に従って有効かどうかはよくわかりません。確かに言えることは、Web ブラウザーが正しく解釈するということです。

ここが興味深い部分です。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を urlencode してみてください。Locationたとえば、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

Darin Dimitrovが説明しているように、ヘッダーのエンコードはHttpWebResponseクラスのバグが原因であると思います。ヘッダーにCookieを追加したい場合(Set-Cookie)、このCookieにASCII以外の文字が含まれるという同じ問題が発生しました。私たちの特定のケースでは、これはノルウェー語の文字「Æ」、「Ø」、および「Å」(大文字と小文字)になります。を機能させる方法を理解できませんでしたが、CookieのBase64エンコーディングHeaderEncodingを使用した回避策を見つけました。これは、クライアント側とサーバー側の両方を制御している場合にのみ機能することに注意してください(または、サーバー側のコードの担当者に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 に答える
1

戻り文字列が不正な形式であるとは思いません...どのようにして不正な形式であると判断しますか? 文字列は、ギリシャ語の文字列を簡単に表現できる utf-8 のような Unicode 形式にする必要があります。

文字列を表現するためのギリシャ語フォントを持っていない可能性がありますか?

于 2009-12-11T15:48:56.130 に答える