|
网页协议相关知识:[转载]
在WINDOWS平台,可以实现HTTP访问的对象和API很多,一般常见的有下面几种
API 方式 WinINet, WinHTTP, WinSock, ws2_32
对象方式 MSXML2.XMLHTTP, Microsoft.XMLHTTP, WinHttp.WinHttpRequest, MSXML2.ServerXMLHTTP
先来了解一下,这些东西都是什么
Winsock:
工作于网络层和传输层的开发库,对于编写TCP,UDP,以及原始IP通信程序非常合适。函数原形也基本符合Unix socket标准。Windows平台上的大多数程序,如QQ,讯雷等都基于其开发,依赖于winsock.dll。但winsock很麻烦,要自己拼接,解压,工作量非常庞大。
ws2_32:
Windows Sockets应用程序接口, 用于支持Internet和网络应用程序,是Winsock的升级版本,在兼容的基础上增加了不符合Unix socket标准,但更适合Windows平台的库函数,一般以WSA*开头,现代的大多数Windows平台程序也都开始依赖于此库,依赖于ws2_32.dll。
WinInet:
Windows Internet扩展库,工作于应用协议层,提供了http,ftp,gopher协议的实现,为基于以上三种协议的程序开发提供基础平台,需要说明的是,尽管WinInet工作于应用层,但其本身wininet.dll的实现并不依赖于winsock.dll或ws2_32.dll,而是独立存在的(WinInet.dll)。至少目前的版本是这样。基于WinInet的应用程序最著名的例子就是IE了。WinINet是一种比WinHTTP更老的技术, 它被设计为一个HTTP客户端平台, 用于交互式桌面应用程序。
WinHttp:
也是工作于应用协议层,提供了http协议的实现。看起来与WinInet有重复的部分,没错,WinHttp就是为了替换WinInet中的http部分的,WinHTTP比WinINet更加安全和健壮,而且还为http服务器端开发提供了库函数,可以这么认为WinHTTP是WinINet的升级版本。如果进行现代http的开发,建议使用WinHTTP而不是WinInet。使用WinHTTP进行开发的著名例子就是Google的浏览器Chrome,但是Chrome2.0以后版本google放弃了winhttp而是使用了自己开发的http库,这也是为了使chrome实现跨平台的重要举措。另外,WinHttp.dll也不依赖于winsock或ws2_32,也是独立运行的。WinHTTP提供了两种编程方式, 一种是API, 另一种是COM组件(对象)。
XMLHTTP 对象:
XMLHTTP为客户端应用程序而设计,并依赖于基于Microsoft Win32 Internet (WinInet) 而构建的URLMon。ServerXMLHTTP为服务器应用程序而设计,并依赖于新的HTTP客户端堆栈WinHTTP。ServerXMLHTTP提供了可靠性和安全性,并且是服务器安全的。
API方式由于在按键里实现起来非常麻烦(有的参数需要以结构体的方式传入按键精灵目前不支持),
所以这里就不讲API方式了,那么对象方式,这几个又有什么区别呢?
"Microsoft.XMLHTTP" 微软官网上说这是MSXML 2.x系列版本的progid。比较古老,简单用用可以。
"MSXML2.XMLHTTP" 相当于 "MSXML2.XMLHTTP.3.0"
"Msxml2.XMLHTTP.4.0"
“Msxml2.XMLHTTP.5.0"
"Msxml2.XMLHTTP.6.0"
以上几个对象,在不同系统中不一定都存在,使用前可以测试一下,一般的说,安装了office 2007之后,除了4.0,别的应该都可以使用的。
上述对象依赖于Microsoft Win32 Internet (WinInet),与IE同内核的,他们的COOKIE和缓存是和IE共用的,要是你能解决跨域问题,用IE登录某站后,再用他们登录也会是登录状态的。所以他们和IE一样是有本地缓存的,同一网页缓存未过期,请求过一次再次请求会很快。因为这时是直接读取了缓存数据。
这也是为什么有些人用这个组件做实时数据抓取的时候,发现网页数据已刷新,而使用代码采集到的数据却更新不及时的原因。
MSXML2.XMLHTTP访问网页可以一般很方便cookie是自动处理,用setRequestHeader方法可以指定其他http头但不能指定cookie。5.0之后可以指定cookie。但Msxml2.XMLHTTP.6.0版本不能设置referer的(好像微软出于安全原因给去掉了),今天测试发现5.0也没有Referer。
"WinHttp.WinHttpRequest.5.1"
WinHTTP比WinINet更加安全和健壮,这个组件独立于IE,没有本地缓存,其代理服务器的设置也是独立于IE的(使用Proxycfg.exe程序设置代理),支持网页重定向,支持修改Cookie和referer,该组件支持HTTPS。Winhttp使用起来适应性最广,参数较多。
WinHTTP在编码转换上与其他组件不同的是,返回的Head如果没有Content-Type: text/html; charset=utf-8的标识,就不转换UTF-8编码(Win7测试发现),即使返回的数据有UTF-8的BOM头(239,187,191)也不转换。
"Msxml2.ServerXMLHTTP"
"Msxml2.ServerXMLHTTP.3.0"
"Msxml2.ServerXMLHTTP.4.0"
"Msxml2.ServerXMLHTTP.5.0"
"Msxml2.ServerXMLHTTP.6.0"
这个对象依赖于 HTTP 客户端堆栈 WinHTTP,所以很多用法与WinHttp类似。
ServerXMLHTTP可以用SetTimeouts自定义超时,XMLHTTP是默认超时。
ServerXMLHTTP在内部支持重定向,可以跨域访问,即你访问的地址如果跳到另外的域名去了,它也可以继续请求页面,而XMLHTTP会抛出异常,说:禁止访问
如果你用的是MSXML2.ServerXMLHTTP.4.0及更高版本的对象,那么可以用.getOption(-1) 来获得最终页面地址 http://support.microsoft.com/kb/308607/zh-cn
新版ServerXmlhttp的referer也被微软封掉了
WinHttpRequest object 相关资料
http://msdn.microsoft.com/en-us/ ... 6%28v=vs.85%29.aspx
WinHttpRequestOption enumeration 相关资料
http://msdn.microsoft.com/en-us/library/aa384108.aspx
WinHttp.WinHttpRequest.5.1 相关资料
http://www.playes.net/Blog/595.asp
总结:
论稳定性和功能强大,依次排序:
WinHTTP>ServerXMLHTTP>MSXML2.XMLHTTP>Microsoft.XMLHTTP
所以,我们只需要用WinHTTP就可以了 |
|