问题:

目标地址:

http://www.baidu.com/baidu.php?url=a000000aa.7D_ifdr1XkSUzuBz3rd2ccvp2mFoJ3rOUsnx8OdxeOeOLxSeqeS-OiOvr8Pe7erQKM9ks43xuMWJuBCrsN4tEwdsRP5QfHPGmsSXOj_tTr14mx5I9qxU9vIrZ1L3xUY3IOH9tqvZu_seOgj4e_r14mI-XZ1lTrOGsS8Oj4SrZx8se59RojPakbzUJO7f.

使用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,对网址参数进行正确的编码。(感觉好难!)

未完待续...

HttpWebRequest 跳转后(301,302)ResponseUri乱码问题的更多相关文章

  1. nginx 301 302跳转配置总结

    首先看简单的代码示例,关于nginx 301 302跳转的. 301跳转设置: server { listen 80; server_name 123.com; rewrite ^/(.*) http ...

  2. PHP 取302跳转后真实 URL 的两种方法

    1 . 第一种,CURL形式[感觉处理略慢,代码偏多] $url = '将跳转的URL'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url) ...

  3. 详解重定向(HTTP状态码301/302/303/307/408)附例子

    本文为原创文章,转载请注明出处. 今天打算好好把状态码301.302.303.307.308好好撸一遍,并会测试下一些例子. 状态码的解释 我们都知道重定向与这几种状态码有关,来看下这几种HTTP状态 ...

  4. 用Java和Nodejs获取http30X跳转后的url

    用Java和Nodejs获取http30X跳转后的url 转 https://calfgz.github.io/blog/2018/05/http-redirect-java-node.html 30 ...

  5. http status 301/302 & java重定向/转发

    一.301/3021.什么是301转向?什么是301重定向? 301转向(或叫301重定向,301跳转)是当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息(header) ...

  6. HTTP 的重定向301,302,303,307(转)

    HTTP 的重定向301,302,303,307(转) (2012-12-11 11:55:04) 转载▼ 标签: 杂谈 分类: 网络 301 永久重定向,告诉客户端以后应从新地址访问.302 作为H ...

  7. HTTP状态码及其含义 503 500 401 200 301 302

    下表显示了常见的HTTP 1.1状态代码以及它们对应的状态信息和含义. 应当谨慎地使用那些只有HTTP 1.1支持的状态代码,因为许多浏览器还只能够支持HTTP 1.0.如果你使用了HTTP 1.1特 ...

  8. Python requests 301/302/303重定向(跨域/本域)cookie、Location问题

    今天使用request的get方法获取一个网站的登录页信息,结果使用charles抓包的时候发现该网站登录页303(重定向的问题),网上查了很多资料,原因如下: 一.cookie 原因:利用reque ...

  9. 获取经过跳转后的url地址

    粗略一算,不写code已经好几个月了. 昨日受兄弟所托,为他写了一个小小的程序. 程序功能: 自动获取跳转后的Url地址 如下图所示: (newUrl.txt为转换后的地址信息...) 实现过程: 每 ...

随机推荐

  1. IOS代码片段

    2017-08-03 获取应用程序委托FKAppDelegate* appDelegate = [UIApplication shareApplication].delegate 2017-08-03 ...

  2. springboot server.address 配置问题

    1. server.address 为对应机器ip地址时 ,如 18.10.x.x 此时访问该服务只能使用 ip 访问 . 2. 配置为 127.0.0.1 时  可以使用 localhost  和  ...

  3. jvm 基础

    1. JDK 包含 java 程序设计语言,JVM, Java API类库. java 开发最小环境 2. JRE : Java API类库中java se API 子集和java 虚拟机(HotSp ...

  4. Redis学习笔记:windows上redis的安装运行

    Redis的windows版本地址https://github.com/MicrosoftArchive/redis 下载之后解压之 在当前解压目录下可以看到如下文件 在当前目录下打开命令行窗口,输入 ...

  5. OneZero第三周——预完成功能点统计

    本周OneZero将完成“摇一摇”功能. 功能点统计如下: 1.点击主页面“摇一摇”按钮,进入摇一摇界面. 2.摇一摇界面布局(上,中,下). 3.摇动手机,在摇一摇界面中显示一条消费记录. 4.继续 ...

  6. 20155312 实验一《Java开发环境的熟悉》实验报告

    (一)命令行下Java程序开发 截图如下: 打印学号: 遇到的问题及 编译时如果还使用javac -d bin 文件名,就会出错 解决:package包是将编译文件放入指定包中 注意:代码中有pack ...

  7. BZOJ 1029 [JSOI2007]建筑抢修 (贪心 + 优先队列)

    1029: [JSOI2007]建筑抢修 Time Limit: 4 Sec  Memory Limit: 162 MBSubmit: 5452  Solved: 2422[Submit][Statu ...

  8. spring boot jpa 多条件组合查询带分页的案例

    spring data jpa 是一个封装了hebernate的dao框架,用于单表操作特别的方便,当然也支持多表,只不过要写sql.对于单表操作,jpake可以通过各种api进行搞定,下面是一个对一 ...

  9. SSM_CRUD新手练习(3)创建数据库

    在上一节我们已经完成了基本的SSM配置,现在需要创建我们数据库. 我们需要两张表分别为tbl_emp(员工表)和tbl_dedpt(部门表).同时d_id是部门表对应dept_id的外键. 需要注意的 ...

  10. android 数据库更新

    SQLiteOpenHelper封装       继承SQLiteOpenHelper类,在构造方法中分别需要传入Context,数据库名称,CursorFactory(一般传入null,为默认数据库 ...