在网络编程中,经常需要从Web服务器获取信息。HTTP协议提供了GET和POST两种命令来实现这一需求。本文将介绍如何使用C++编写程序,通过GET和POST命令从Web服务器检索原始信息。
本文介绍的工具是一个包装了可重用函数的实用程序,允许程序通过一种嵌入在程序中的“微型浏览器”访问Web。这种代码有很多用途。像用户一样从一个网页浏览到另一个网页的程序通常被称为蜘蛛(spiders)、机器人(bots)或爬虫(crawlers)。这些程序通常用于编目网站、从Web导入外部数据,或者简单地向Web服务器发送命令。可以扩展这里介绍的类的功能性,以多种方式从互联网检索信息。
工具的核心是Request类。关键函数是SendHTTP()。这个函数接受5个参数并返回一个整数。第一个参数是要POST或GET的URL。第二个参数指定在此请求期间要传递的任何其他HTTP头。第三和第四个参数指定要发布的数据和数据长度。第五个参数是一个指向HTTPRequest结构的指针,它将保存Web服务器发送和返回的头和消息。
SendHTTP()首先解析URL字符串。URL是一个指定互联网上资源确切位置的地址。URL有几个部分,其中一些是可选的。URL的一个例子是:http://www.codetools.com:80/index.html。URL的第一部分是协议,它指定如何接收资源。协议之后是主机名。这可以是域名或IP地址。主机之后是端口号。每种协议都有一个默认端口号,如果没有指定端口号,则使用默认端口。默认HTTP端口是端口80。端口之后是向指定Web服务器发出的请求。如果没有指定,它默认为'/',请求Web服务器的根文档。
接下来,SendHTTP()通过调用WinSock的WSAStartup()初始化WinSock库。建立套接字连接后,SendHTTP()向服务器发送请求。有两种形式的HTTP请求。第一种,也是更简单的形式,是HTTP GET。HTTP GET除了请求头和URL之外,不会向Web服务器发送任何额外的信息。HTTP GET通常使用URL本身发送额外的信息:
http://localhost/projects/HTTP/TestGet.asp?name=fred&age=22
第二种形式,HTTP POST,会随请求一起发送数据,与URL分开。通常,HTTP POST包括头:
Content-Type:application/x-www-form-urlencoded
如果没有这个头,一些Web服务器(特别是运行在IIS上的ASP)将无法识别参数。HTTP POST有两个部分。第一部分是HTTP头,就像GET一样。头包含实际的请求和额外的信息。与GET不同的是,POST在头之后包含数据(用空行与它们分开)。
Web服务器收到GET或POST请求后,会发送回一个响应。响应有两个部分:头后跟数据(用空行将两者分开)。HTTP头的第一行指定了请求的状态。它以一个数字错误代码开始。100-199是一个信息性消息,通常不使用。200-299表示请求成功。300-399表示请求的资源已移动;Web服务器使用这个进行重定向。400-499表示客户端错误。500-599表示服务器错误。头之后是GET或POST请求返回的数据。这通常在浏览器屏幕上看到。
MFC对话框项目用作Request类的包装器。在对话框容器中插入了一个Microsoft Web Browser控件的实例。这使得导航数据、执行GET或POST命令变得非常容易。该控件有两种用途:
当用户从浏览器发出请求时,控件触发OnBeforeNavigate2事件,该事件被对话框程序捕获。在OnBeforeNavigate2Explorer1函数中,用于发现是GET还是POST,发送到Web服务器的头和发布的数据。
如果用户想要使用SendHTTP引擎,输入所需的URL,完成'SendHTTPrequest'和'PostData'(如果是POST)字段,检查单选按钮GET或POST,然后点击'Go'按钮。IE控件将在m_HTTPbody字符串变量中加载从SendHTTP()函数接收的HTML格式化数据。HTML加载是在OnButtonViewHttp()中完成的。
输入URL地址,然后点击Go按钮。右侧有一个微型浏览器,显示页面。在页面上的链接和按钮上导航,以及在'PostData'、'SendHTTPrequest'和'ReceiveHTTPrequest'上,将接收相应的数据。单选按钮Get/Post会自动修改 - IE实例知道是否进行GET(点击了一个链接)或POST(点击了一个按钮)。
可以在'SendHTTPrequest'编辑框中输入头,在'PostData'编辑框中输入POST数据,然后点击'Go'按钮。浏览器将使用'SendHTTPrequest'和'PostData'字段提交的头和数据导航到地址。