ج # HttpWebresponse رأس ترميز
-
19-09-2019 - |
سؤال
لدي المشكلة التالية. أتصل بعنوان أعرفه توظف إعادة توجيه 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 = "بعيدا).