魔爪的作者Djunny曾经说过,下载的主要问题是要熟悉各个网络的不同特点(比中文确切的英文单词应该是whimsicalness)。这点我现在是深有体会。比如大部分网站的url是基于utf8的,但是有些却是基于GB2312的,这些网站wininet可能不能正确处理。
其实ie是能正确处理的,但是微软却没有把相应的功能放到wininet里面,这目的只有一个,微软想使得ie的功能比wininet多一点,也就是故意要让程序员麻烦一些。何苦?你让人家难受,人家自然要找你的漏洞。
为何不放弃wininet而用liburl之类的程序,毕竟后者若干年的开发,久经考验。原因:做个简单的工具虽然可以用libcurl,但是发布uread这样的应用就不好,要至少多一个dll,麻烦。
好,下面谈谈“锟斤拷”的问题。其实这个问题已经有人谈过,参见 http://hooopo.javaeye.com/blog/352451
. 但是这里是由wininet引起的。采用简单的wininet调用,访问:
http://www.sjtxt.com/soft/download.asp?softid=21519&downid=2&id=21525
你会发现重定向到一个网址:
http://down1.sjtxt.com/2010-2/
锟斤拷士锟斤拷陆.rar
为什么这里显示“锟斤拷”,就是wininet没有正确地解码,把这个网站返回的gb码当成utf8, 先转为utf16,然后又转成utf8,最后按照gb显示出来就变成了“锟斤拷”了(实际的转向地址为http://down1.sjtxt.com/2010-2/
斗士大陆.rar,感兴趣的可以把这个“锟斤拷”如何出来的详细推演一下)。
处理这个问题的办法是不要让wininet进行自动重定向(301 302之类),自己进行处理。这下更麻烦了,本来用wininet就是为了省事,没想到却要多写若干代码。
还有一个可笑的事情是,wininet的ansi版本和unicode版本不同,后者自动地把url的path部分当成utf8处理,而前者不会。我有些工具是用delphi7写的,有些是用delphi 2010写的,对某些网站,后者则要调用以下这样的函数
InternetSetOption(hSession, 100{INTERNET_OPTION_CODEPAGE_PATH}, @CP_CHINA, sizeof(CP_CHINA));
其中最新的常量,Delphi中还没有定义(CP_CHINA = 936)。
这些问题的解决,只是把工具做的好一些。实际上没有什么意义,都是微软没有把事情做好。你做好点,大家就可以做些有意义的事情是不?