Question

J'ai le problème suivant. Je contacte une adresse que je connais utilise une redirection 301.

à l'aide HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl); et loHttp.AllowAutoRedirect = false; pour que je ne suis pas redirigés.

Maintenant je l'en-tête de la réponse afin d'identifier la nouvelle URL.

à l'aide loWebResponse.GetResponseHeader("Location");

Le problème est que depuis cette URL contient des caractères grecs la chaîne retournée est tout mêlé (en raison de l'encodage).

La codewise complète de l'image:

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"];
Était-ce utile?

La solution

Si vous laissez le comportement par défaut (loHttp.AllowAutoRedirect = true) et votre code ne fonctionne pas (vous ne soyez pas redirigé vers la nouvelle ressource), cela signifie que le serveur ne codant pas correctement l'en-tête de Location. Est-ce que la redirection fonctionne dans le navigateur?

Par exemple, si l'URL de redirection est http://site/Μία_Σελίδα l'en-tête de localisation doit ressembler http://site/%CE%95%CE%BD%CE%B9%CE%B1%CE%AF%CE%BF_%CE%94%CE%B5%CE%.


Mise à jour:

Après avoir étudié davantage la question que je commence à soupçonner qu'il ya quelque chose de étrange avec HttpWebRequest. Lorsque la demande est envoyée le serveur envoie la réponse suivante:

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">

Comme on peut le voir l'en-tête Location contient des caractères grecs qui ne sont pas URL encodée. Je ne suis pas tout à fait sûr que cela est valable selon la spécification HTTP . Ce que nous pouvons dire avec certitude est qu'un navigateur Web interprète correctement.

Voici la partie intéressante. Il semble que HttpWebRequest ne pas utiliser le codage UTF-8 pour analyser les en-têtes de réponse parce que l'analyse de l'en-tête de Location donne: http://www.site.com/buy/κινηÏή-ÏÏαθεÏή-ÏηλεÏÏνία/c/cn69569/, ce qui bien sûr est faux et quand il essaie de rediriger vers cet emplacement le serveur répond avec une nouvelle redirection et ainsi de suite jusqu'à ce que le nombre maximum de réoriente est atteint et une exception est levée.

Je ne pouvais pas trouver un moyen de spécifier l'encodage utilisé par HttpWebRequest lors de l'analyse des en-têtes de réponse. Si nous utilisons tcpclient manuellement fonctionne parfaitement bien :

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/
    }
}

Je suis vraiment intrigué par ce comportement. Est-il possible de spécifier l'encodage correct utilisé par HttpWebRequest? Peut-être un en-tête de demande doit être réglée?

Pour contourner ce problème, vous pouvez essayer de modifier la page asp qui effectue la redirection et urlencode l'en-tête de Location. Par exemple, lorsque dans une application ASP.NET vous effectuez une Response.Redirect(location), l'emplacement sera automatiquement codé en HTML et les caractères non standard seront convertis en leurs entités correspondantes.

Par exemple, si vous faites: Response.Redirect("http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/"); dans une application ASP.NET l'en-tête de Location sera réglé sur:

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

Il semble que ce n'est pas le cas avec ASP classique.

Autres conseils

Je ne me attends pas la chaîne de retour à malformé ... Comment déterminerez-vous qu'il est malformé? La chaîne doit être dans un format unicode comme utf-8 qui serait en mesure de représenter la chaîne grecque facilement.

Il se pourrait que vous n'avez tout simplement pas les polices de caractères grecs pour représenter la chaîne?

Darin Dimitrov explique, je crois que le codage d'en-tête est causé par un bogue dans la classe HttpWebResponse. Nous avons eu le même problème que nous voulions ajouter un cookie à l'en-tête (Set-Cookie) et ce cookie contiendrait des caractères non-ascii. Dans notre cas spesific ce serait les lettres norvégiennes « Æ », « Ø » et « A » (en minuscules et). Nous ne pouvions pas comprendre comment obtenir le HeaderEncoding au travail, mais nous avons trouvé un travail autour de l'utilisation Base64 encodage du cookie. Notez que cela ne fonctionnera que si vous êtes dans le contrôle à la fois du côté client et serveur (ou vous pouvez convaincre les responsables du code côté serveur pour ajouter l'encodage base64 pour vous ... )

Du côté du serveur:

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);

Du côté client:

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

Notez que cookieDataAsUtf8Base64Encoded sur le côté client est la partie de données du cookie (qui est 'MonCookie = [données]', où 'MyCookie =' est dépouillé).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top