使用HttpSendRequest函数POST数据时应该注意的一点

测试用例代码

 CString szHeaders;
 szHeaders ="EmployeeID: "+UserID+"/r/n";
 szHeaders+="EmployeePassword: "+Password+"";
 
// HTTPRequest Response;
// memset(&Response, NULL, sizeof(HTTPRequest));
// if (!MCHttp.SendRequestEx(m_VerbType, szURL, HTTP_VERSION_1_1, TEXT("*/*"), TEXT("PervasiveBiz"), szHeaders,
//      szSendBuffer, 60000, &Response))
 CString strServerName;
 CString strObject;
 INTERNET_PORT nPort;
 DWORD dwServiceType; 
 if (!AfxParseURL(szURL, dwServiceType, strServerName, strObject, nPort) ||
  dwServiceType != AFX_INET_SERVICE_HTTPS && dwServiceType != AFX_INET_SERVICE_HTTP)
 {
  return -2;
 }

 HINTERNET m_hOpen;
    HINTERNET m_hConnect;
    HINTERNET m_hRequest;  
 m_hOpen = InternetOpen(TEXT("PervasiveBiz"), INTERNET_OPEN_TYPE_DIRECT,NULL, 0, 0);
 if (!m_hOpen)
 {
  return -1;
 }
 
 if (!(m_hConnect = InternetConnect(m_hOpen, strServerName,  nPort,  NULL, NULL, dwServiceType,  0, 0)))
 {
  InternetCloseHandle(m_hOpen);
  return -1;
 }
 
 LPTSTR AcceptTypes[2] = {TEXT("*/*"), NULL};
 DWORD dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE;
 // Open an HTTP request handle.

 if (!(m_hRequest = HttpOpenRequest (m_hConnect, TEXT("POST"), strObject, HTTP_VERSION, NULL, (LPCTSTR*)AcceptTypes,
   dwFlags, 0)))
 {
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  return -1;
 }
 
 DWORD dwHttpTimeout = TIME_OUT;
 if(!InternetSetOption(m_hRequest,INTERNET_OPTION_CONNECT_TIMEOUT,&dwHttpTimeout,sizeof(DWORD)))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  return -1;
 }
 if(!InternetSetOption(m_hRequest,INTERNET_OPTION_SEND_TIMEOUT,&dwHttpTimeout,sizeof(DWORD)))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  return -1;
 }
 if(!InternetSetOption(m_hRequest,INTERNET_OPTION_RECEIVE_TIMEOUT,&dwHttpTimeout,sizeof(DWORD)))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);;
  return -1;
 }

// MessageBox(NULL,  szSendBuffer,szHeaders, 0);

重点要注意的地方,HttpSendRequest的第三个参数必须为多字节编码格式,否则服务器端会出错的。花了一天半的时间调试出来的结论。如果不进行转换,服务器端只会接收一半数据,后面的数据将会收不到。
 byte* pszData = new byte[szSendBuffer.GetLength()];
 char *pConten = new char[szSendBuffer.GetLength()];
 memset(pszData,0,szSendBuffer.GetLength());
 memset(pConten,0,szSendBuffer.GetLength());
 WideCharToMultiByte( CP_ACP, 0, szSendBuffer.GetBuffer(0),
   -1, pConten, szSendBuffer.GetLength(), NULL, NULL );
 memcpy(pszData, pConten, szSendBuffer.GetLength());
 
 int len = strlen((char*)pszData);
 int len2 = szSendBuffer.GetLength();
 //MessageBox(NULL, szSendBuffer, str);
 if(HttpSendRequest(m_hRequest, szHeaders, szHeaders.GetLength(), pszData, szSendBuffer.GetLength())
   == FALSE)
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  return -1;  
 }

 DWORD dwSize;
 HttpQueryInfo(m_hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &dwSize,NULL);

 TCHAR* lpHeaders = new TCHAR [dwSize];
 if (!HttpQueryInfo (m_hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, (LPVOID) lpHeaders, &dwSize, NULL))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  delete[] lpHeaders;
  return -1;
 }
 
// MessageBox(NULL, lpHeaders, _T("HttpQueryInfo"),  0);

 TCHAR szHttpStatus[4] = {0};
 memcpy(szHttpStatus,lpHeaders+wcslen(_T("HTTP/1.1 ")),3*sizeof(TCHAR));
 int dwHttpStatus = 0;
 dwHttpStatus =_wtoi(szHttpStatus);
 if ((dwHttpStatus<200)||(dwHttpStatus>300))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  delete[] lpHeaders;
  return -1;
 }

 if(!InternetReadFile (m_hRequest, (LPVOID)(cResponse),32*1024, &dwSize))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  delete[] lpHeaders; 

  return -1;
 }
 if(dwSize == 0)
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  delete[] lpHeaders; 
  return -1;  
 }
 

 HttpQueryInfo(m_hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &dwSize,NULL);
 if (!HttpQueryInfo (m_hRequest, HTTP_QUERY_RAW_HEADERS_CRLF,
   (LPVOID) lpHeaders, &dwSize, NULL))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  delete[] lpHeaders; 
  return -1;
 }
 
 memcpy(szHttpStatus,lpHeaders+wcslen(_T("HTTP/1.1 ")),3*sizeof(TCHAR));
 dwHttpStatus = _wtoi(szHttpStatus);
 if ((dwHttpStatus<200)||(dwHttpStatus>300))
 {
  InternetCloseHandle(m_hRequest);
  InternetCloseHandle(m_hConnect);
  InternetCloseHandle(m_hOpen);
  delete[] lpHeaders;
  return -1;
 }

// MessageBox(NULL, lpHeaders, _T("lpHeaders"),  0);
 delete[] lpHeaders; 
 InternetCloseHandle(m_hRequest);
 InternetCloseHandle(m_hConnect);
 InternetCloseHandle(m_hOpen);
 return SENDDATA_SCUCCEED ;

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
此示例演示在 Internet Explorer 4.0 WinInet.dll 中引入并记录在 Internet 客户端 SDK 中的 HttpSendRequestEx 函数的正确用法。 原始的 HttpSendRequest 函数有这样一个重大限制: 所有请求的数据都有一个缓冲区调用该函数将提供。这是通常不方便、 导致在某些客户端应用程序中,性能较差,可能会无法上载大量数据从客户端计算机使用有限的内存。新的 HttpSendRequestEx 函数允许启动请求,发送出数据分小段为可用,然后结束后已发送的所有数据的请求的程序。为了使此函数以处理计算机上必须安装 Internet Explorer 4.0。下列文件已可从 Microsoft 下载中心下载: Hsrex.exe 有关如何下载 Microsoft 支持文件的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章: 119591 如何从在线服务获得 Microsoft 支持文件微软已对此文件进行病毒扫描。Microsoft 使用该文件投递日期可用的最新的病毒检测软件。该文件存储在安全增强型服务器上,以防止对文件进行任何未经授权的更改。 Hsrex.exe 是自解压的存档文件,其中包含 BigPost.cpp (演示程序代码) 和 Readall.asp,一个 Active Server Pages (ASP) 脚本将读取所有发送 POST 请求中的数据。Readall.asp 是 BigPost,可以使用 Microsoft 互联网信息服务器 (IIS) 版本的支持 ASP 作为示例目标提供。对于其他 Web 服务器,您需要提供相应的服务器脚本来读取数据。 若要编译此程序包含在 Microsoft Visual C++ 5.0,请执行以下步骤: 1.运行 Visual C++ 和创建一个新的 Win32 控制台应用程序调用"BigPost"。 2.在目录中创建项目的位置,运行 Hsrex.exe。 3.将 BigPost.cpp 添加到 BigPost 项目。 4.转到项目设置对话框中,单击链接选项卡,然后添加到 WinInet.lib"对象/库模块:"字段。 5.请确保配置 Visual C++,以便编译器和链接器将使用 Wininet.h 和 Wininet.lib 从 Internet 客户端 SDK。如果未能做到这一点,将导致编译器或链接器错误。原型和 HttpSendRequestEx 的导出不包含 Visual C++ 中包含的包括和库文件。 6.生成项目。它将创建 BigPost.exe。 在程序运行,如下所示: BigPost < 大小 >< 服务器 >< 路径 > 例如,以下将开机自检 1 兆字节 (1024 KB) 到 http://yourserver/scripts/ReadAll.asp: 您的服务器 /scripts/ReadAll.asp BigPost 1024
VB中的POST回调函数可以通过Wininet.dll库中的InternetOpen、InternetConnect、HttpOpenRequestHttpSendRequest函数来实现。具体步骤如下: 1. 使用InternetOpen函数初始化一个会话句柄。 2. 使用InternetConnect函数连接到服务器。 3. 使用HttpOpenRequest函数创建一个HTTP请求句柄。 4. 使用HttpSendRequest函数发送HTTP请求。 5. 使用InternetReadFile函数读取服务器返回的数据。 6. 使用InternetCloseHandle函数关闭会话句柄、连接句柄和请求句柄。 以下是一个简单的VB代码示例: ``` Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Long, ByVal sServerName As String, ByVal nServerPort As Integer, ByVal sUsername As String, ByVal sPassword As String, ByVal lService As Long, ByVal lFlags As Long, ByVal lContext As Long) As Long Private Declare Function HttpOpenRequest Lib "wininet.dll" Alias "HttpOpenRequestA" (ByVal hHttpSession As Long, ByVal sVerb As String, ByVal sObjectName As String, ByVal sVersion As String, ByVal sReferer As String, ByVal lAcceptTypes As Long, ByVal lFlags As Long, ByVal lContext As Long) As Long Private Declare Function HttpSendRequest Lib "wininet.dll" Alias "HttpSendRequestA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal sOptional As String, ByVal lOptionalLength As Long) As Long Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Integer Private Sub PostRequest() Dim hInternetSession As Long Dim hHttpConnection As Long Dim hHttpRequest As Long Dim sServerName As String Dim sObjectName As String Dim sPostData As String Dim sHeaders As String Dim lBytesWritten As Long Dim lBytesRead As Long Dim sResponse As String ' 初始化会话句柄 hInternetSession = InternetOpen("VB POST Request", 0, vbNullString, vbNullString, 0) ' 连接到服务器 sServerName = "www.example.com" hHttpConnection = InternetConnect(hInternetSession, sServerName, 80, vbNullString, vbNullString, 3, 0, 0) ' 创建HTTP请求句柄 sObjectName = "/post.php" hHttpRequest = HttpOpenRequest(hHttpConnection, "POST", sObjectName, "HTTP/1.1", vbNullString, 0, 0, 0) ' 设置POST数据和请求头 sPostData = "name=value" sHeaders = "Content-Type: application/x-www-form-urlencoded" & vbCrLf & "Content-Length: " & Len(sPostData) ' 发送HTTP请求 HttpSendRequest hHttpRequest, sHeaders, Len(sHeaders), sPostData, Len(sPostData) ' 读取服务器返回的数据 sResponse = "" Do Dim sBuffer As String sBuffer = Space(1024) InternetReadFile hHttpRequest, sBuffer, Len(sBuffer), lBytesRead sResponse = sResponse & Left(sBuffer, lBytesRead) Loop While lBytesRead > 0 ' 关闭句柄 InternetCloseHandle hHttpRequest InternetCloseHandle hHttpConnection InternetCloseHandle hInternetSession ' 输出服务器返回的数据 MsgBox sResponse End Sub ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值