سؤال

لدي المشكلة التالية. أتصل بعنوان أعرفه توظف إعادة توجيه 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/Μία_Σελίδα يجب أن تبدو رأس الموقع 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 الصفحة التي تؤدي إعادة توجيه و 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 الكلاسيكي.

نصائح أخرى

لا أتوقع أن تتشوه سلسلة الإرجاع ... كيف تحدد أنها مشوهة؟ يجب أن تكون السلسلة بتنسيق Unicode مثل UTF-8 سيكون قادرا على تمثيل السلسلة اليونانية بسهولة.

يمكن أن يكون لديك فقط الخطوط اليونانية لتمثيل السلسلة؟

كما يوضح دارن ديميتروف، أعتقد أن ترميز الرأس ناتج عن خطأ في فئة HTTPWebresponse. لقد كان لدينا نفس المشكلة التي أردنا فيها إضافة ملف تعريف ارتباط إلى رأس (مجموعة ملفات تعريف الارتباط) وأن ملف تعريف الارتباط هذا سيحتوي على أحرف غير ASCII. في حالة Spisicific، ستكون هذه الرسائل النرويجية "æ"، "،" Å "(في العلوي والسفلي). لم نتمكن من معرفة كيفية الحصول على HeaderEncoding للعمل، ولكن وجدنا العمل حول العمل 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 على جانب العميل هو جزء البيانات من ملف تعريف الارتباط (أي MyCookie = [البيانات] "، حيث يتم تجريد" mycookie = "بعيدا).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top