HttpWebRequest 跳转后(301,302)ResponseUri乱码问题
问题:
使用HttpWebRequest请求之后,ResponseUri为:
http://chongqing.anjuke.com/sale/rd1/?kw=�״�ʮ����&pi=baidu-cpc-cq-shantou1-jx&utm_term=重庆首创十方界
正确跳转地址(使用浏览器请求):
http://chongqing.anjuke.com/sale/rd1/?kw=�״�ʮ����&pi=baidu-cpc-cq-shantou1-jx&utm_term=重庆首创十方界
对比2个地址,可以发现一个奇怪的问题:地址中含有2个urlencode转换后的中文参数,奇怪的是第一个kw参数不同,而第二个utm_term参数确实相同的!这尼玛太神奇吧。。。
那么真相是什么?(找坑)
通过Fidder的Composer工具,模拟请求看看:
通过上图可以看到302响应中的跳转地址,发现了异常:kw参数竟然是乱码!utm_term显示已经urlencode过了。也就有说kw未经过urlencode。被坑1
那么为什么Fidder和HttpWebRequest跳转得到的地址和为啥是%EF...
呢,答案只有一个:他们都使用了.net内部的Uri类型来初始化HttpWebRequest:
HttpWebRequest.Create(new Uri(url))
而Uri 默认对网址中的参数进行了urlencode,而且是用了错误的编码类型进行转化!!!被坑2
如何解决这个问题
计策1:
设置不自动跳转,而后自己解码。。(挫计)
//有些请求的location中带有未urlencode的中文,而默认的http头是用ascii解码的,导致乱码,所以头需要重写编码下
HttpWebRequest.AllowAutoRedirect=false;
var headerStr = Encoding.Default.GetString(hp.ResponseHeaders.ToByteArray());
var oHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var sHeaderLines = headerStr.Replace("\r", "").Split('\n');
for (int i = 0; i < sHeaderLines.Length; i++)
{
int index = sHeaderLines[i].IndexOf(':');
if (index > 0)
{
oHeaders[sHeaderLines[i].Substring(0, index)] = sHeaderLines[i].Substring(index + 1).Trim();
}
}
var link = oHeaders["Location"];
而后在对实现一个Uri,对网址参数进行正确的编码。(感觉好难!)