这个真得高手了,不一般的httpwebrequest的url问题,图

sswwee 2012-05-01 07:24:48

看到红色标注的部分了吧,某网站提交的url部分直接包含gbk汉字的二进制码(不带%的),而如果用httpwebrequest,无论怎么折腾提交出去的url都给转换成%d0%d5%c3%fb带%的这样子,难道只能用tcpclient了吗?

请告诉我HttpUtility.UrlEncode的人士提交一下试试看带不带那个百分号,我要的是不带%的
...全文
620 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
windyoyo 2014-11-03
  • 打赏
  • 举报
回复
我也碰到楼主说的问题了。某个网页的请求:get xxxxxx 这里的xxx是100%没有转义的中文,目测是GBK编码,因为用IE11的开发者工具抓取网络流量显示这段文字是“中国标准时间”,然后在wireshark里面显示的byte字节为d6 d0 b9 fa b1 ea d7 bc ca b1 bc e4,刚好是12字节也就是说双字节表示一个汉字。这样的话通常就是gb2312或gbk,因为utf8的话是18字节,unicode是24字节,都不符合。 找了很多办法都不管用。最后想着可能在哪里转义了这个uri的path,打算用反射去改httpwebrequest的私有对象。然后我在referencesource.microsoft.com找到了httpwebrequest的源码。一看之下傻眼了。 关键部分在这里: private int GenerateRequestLine(int headersSize) { int offset = 0; string pathAndQuery = _Uri.PathAndQuery; int writeBufferLength = CurrentMethod.Name.Length + pathAndQuery.Length + RequestLineConstantSize + headersSize; _WriteBuffer = new byte[writeBufferLength]; offset = Encoding.ASCII.GetBytes(CurrentMethod.Name, 0, CurrentMethod.Name.Length, WriteBuffer, 0); WriteBuffer[offset++] = (byte)' '; offset += Encoding.ASCII.GetBytes(pathAndQuery, 0, pathAndQuery.Length, WriteBuffer, offset); WriteBuffer[offset++] = (byte)' '; return offset; } 如同函数名所说,这个方法是构建Http的请求行,也就是通常的get xxx或post xxx那行。其中关键是: offset += Encoding.ASCII.GetBytes(pathAndQuery, 0, pathAndQuery.Length, WriteBuffer, offset); 这个pathAndQuery就是网址中域名之后的部分。经过实验,不论pathAndQuery使用什么编码(创建httpWebRequest的时候使用new Uri(url, true)能使uri的pathAndQuery保持原来的字符串编码),经过Encoding.ASCII.GetBytes后全给你变成?????(byte 63)。 不知道有没有大神有更好的办法? 附上HttpWebRequest源码地址: http://referencesource.microsoft.com/#System/net/System/Net/HttpWebRequest.cs
lw8122 2013-03-14
  • 打赏
  • 举报
回复
LZ,已经私信联系你,也遇到这个问题,希望能交流一下
sswwee 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 的回复:]

你说的 urlencode还是乱码 可以试试 Web.HttpUtility.UrlEncode("中文", System.Text.Encoding.GetEncoding("gbk")) 不指定encoding 默认是utf8 当然乱码了

哎 不要只分析 不实践啊
[/Quote]
算了算了简单点说吧
TcpClient tc = new TcpClient();
tc.Connect("www.microsoft.com", 80);
string s = "GET /微软\r\n";
s += "Host: www.microsoft.com\r\n";
s += "Connection: Keep-Alive\r\n";
byte[] bt = Encoding.Default.GetBytes(s);
NetworkStream ns = tc.GetStream();
ns.Write(bt, 0, bt.Length);
这样发送你拦截一下,然后你用httpwebrequest弄个一个样的试试。
rayyu1989 2012-05-02
  • 打赏
  • 举报
回复
你说的 urlencode还是乱码 可以试试 Web.HttpUtility.UrlEncode("中文", System.Text.Encoding.GetEncoding("gbk")) 不指定encoding 默认是utf8 当然乱码了

哎 不要只分析 不实践啊
rayyu1989 2012-05-02
  • 打赏
  • 举报
回复
楼主 我说了 你100%拦截错了 包,类似问题不回你了
数据完全是urlencode的
楼主不乖 楼主面壁
sswwee 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 的回复:]

楼主 别逗你,是你拦截错了 不信你ping下 论坛域名的ip 再看看 你拦截的数据的ip
引用 27 楼 的回复:

引用 26 楼 的回复:

楼主测了半天 数据包拦截错了吧
POST /logon.do?processID=updateUserAjax&option=updateUserAjax&name=%B0%D9%B6%C……
[/Quote]
真是愁死我了,你为什么就不能亲自试验一下呢。
sswwee 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 的回复:]

楼主 别逗你,是你拦截错了 不信你ping下 论坛域名的ip 再看看 你拦截的数据的ip
引用 27 楼 的回复:

引用 26 楼 的回复:

楼主测了半天 数据包拦截错了吧
POST /logon.do?processID=updateUserAjax&option=updateUserAjax&name=%B0%D9%B6%C……
[/Quote]

真是愁死我了,您亲自试验一下行不行,我求求你了。
rayyu1989 2012-05-02
  • 打赏
  • 举报
回复
楼主 别逗你,是你拦截错了 不信你ping下 论坛域名的ip 再看看 你拦截的数据的ip
[Quote=引用 27 楼 的回复:]

引用 26 楼 的回复:

楼主测了半天 数据包拦截错了吧
POST /logon.do?processID=updateUserAjax&option=updateUserAjax&name=%B0%D9%B6%C8&gender=1

很正常的编码 谢谢;你截获的请求 是你的360还是金山 偷你的数据吧 把你的请求 偷上传了

……
[/Quote]
sswwee 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

楼主测了半天 数据包拦截错了吧
POST /logon.do?processID=updateUserAjax&option=updateUserAjax&name=%B0%D9%B6%C8&gender=1

很正常的编码 谢谢;你截获的请求 是你的360还是金山 偷你的数据吧 把你的请求 偷上传了
[/Quote]
您要是会用sniffer类的工具,用他的页面提交一下拦截,然后用您的程序提交一下拦截,就会发现不同了。
sswwee 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

楼主测了半天 数据包拦截错了吧
POST /logon.do?processID=updateUserAjax&option=updateUserAjax&name=%B0%D9%B6%C8&gender=1

很正常的编码 谢谢;你截获的请求 是你的360还是金山 偷你的数据吧 把你的请求 偷上传了
[/Quote]
你点一下个人资料再看,肯定是乱码
rayyu1989 2012-05-02
  • 打赏
  • 举报
回复
楼主测了半天 数据包拦截错了吧
POST /logon.do?processID=updateUserAjax&option=updateUserAjax&name=%B0%D9%B6%C8&gender=1

很正常的编码 谢谢;你截获的请求 是你的360还是金山 偷你的数据吧 把你的请求 偷上传了
sswwee 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]

你错了 他的第一个请求 只是确认用户是否存在,返回200表示存在 然后才开始传数据引用 22 楼 的回复:

引用 19 楼 的回复:

大虾 你直接把他ajax 请求的url给出来就是了 还要我去注册...

这真是百年一遇的,我从没见过第二个提交页面是那样的,即使那个站内也是唯一的。就说用他页面提交,用的post方法但是没有数据,数据放在了url里,而且是未编码的gbk。
……
[/Quote]

您亲自试一下行不行啊,我怎么说也说不清楚,你怎么都不会相信,真的是很奇怪,如果你嫌注册麻烦,我可以给你一个注册好的账号,如果那个提交你能用httpwebrequest搞定,回来怎么骂我都行好吧。
chen870201 2012-05-02
  • 打赏
  • 举报
回复

好专业
rayyu1989 2012-05-01
  • 打赏
  • 举报
回复
你错了 他的第一个请求 只是确认用户是否存在,返回200表示存在 然后才开始传数据[Quote=引用 22 楼 的回复:]

引用 19 楼 的回复:

大虾 你直接把他ajax 请求的url给出来就是了 还要我去注册...

这真是百年一遇的,我从没见过第二个提交页面是那样的,即使那个站内也是唯一的。就说用他页面提交,用的post方法但是没有数据,数据放在了url里,而且是未编码的gbk。
[/Quote]
sswwee 2012-05-01
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]

大虾 你直接把他ajax 请求的url给出来就是了 还要我去注册...
[/Quote]
这真是百年一遇的,我从没见过第二个提交页面是那样的,即使那个站内也是唯一的。就说用他页面提交,用的post方法但是没有数据,数据放在了url里,而且是未编码的gbk。
rayyu1989 2012-05-01
  • 打赏
  • 举报
回复
给出地址就是了 -_,-
sswwee 2012-05-01
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]

大虾 你直接把他ajax 请求的url给出来就是了 还要我去注册...
[/Quote]
不注册进入那个页面怎么提交呢,提交了怎么能看到效果呢。
rayyu1989 2012-05-01
  • 打赏
  • 举报
回复
大虾 你直接把他ajax 请求的url给出来就是了 还要我去注册...
sswwee 2012-05-01
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 的回复:]

把他网址亮出来
[/Quote]
中华网论坛,注册一账号,点个人信息中心,点编辑个人信息,弹出来的那个提交出去,你试试用httpwebrequest无论你怎么折腾到头来都是乱码,只能直接用socket或者tcpclient
sswwee 2012-05-01
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

换句话说,r就是二进制为d0d5c3fb的字符串
[/Quote]
我试了您提供的办法,拦截了一下还是
GET /?name=%C3%90%C3%95%C3%83%C3%BB HTTP/1.1
Host: www.baidu.com
Connection: Keep-Alive

还是带%的,那个网站是不带%的
您要是不相信,我把那个网站告诉你,您自己用httpwebrequest试试可以吗?真的是很古怪,我估计基本大家都碰不到这种情况所以才以为我不会转码吧,没有要挑战谁的意思。
加载更多回复(16)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧