纯C中使用IWebBrowser2发送POST请求,服务器无法接收参数问题
问题:纯C编写IWebBrowser2 POST请求,服务器接收不到POST参数
我需要用纯C编写基于IWebBrowser2的POST请求程序,微软文档指出:
PostData指定的POST数据需以SAFEARRAY数据结构传递。VARIANT应属于VT_ARRAY|VT_UI1类型,并指向SAFEARRAY数据类型。SAFEARRAY数据类型的元素类型应为VT_UI1、一维,且元素数量等于POST数据的字节数。
但当我把请求发送到本地服务器时,服务器完全接收不到$_POST['name']和$_POST['sub']变量,就像没发送任何数据一样。
我的代码如下:
INT32 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT32 nShowCmd) { HRESULT HResult = 0; CLSID CLSID_IE; IWebBrowser2 *pWebBrowser; VARIANT vEmpty; VARIANT_BOOL vBusy; VariantInit(&vEmpty); CoInitializeEx(0, COINIT_MULTITHREADED); CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); CoCreateInstance(&CLSID_InternetExplorer, 0, CLSCTX_ALL, &IID_IWebBrowser2, &pWebBrowser); IWebBrowser2_put_Visible(pWebBrowser, VARIANT_FALSE); /* process the formulary data */ LPSTR pPostData = NULL; CHAR strFormulary[] = "sub=gt&name=sdfs"; LPSAFEARRAY FormularyArray = SafeArrayCreateVector(VT_UI1, 0, sizeof(strFormulary)); VARIANT PostData = FormularyArray; SafeArrayAccessData(FormularyArray, (LPVOID*)&pPostData); memcpy(pPostData, &strFormulary, sizeof(strFormulary)); SafeArrayUnaccessData(FormularyArray); /* Set the headers data */ VARIANT Headers; V_VT(&Headers) = VT_BSTR; V_BSTR(&Headers) = SysAllocString(L"Content-Type: application/x-www-form-urlencodedrn"); /* Set POST request */ BSTR bstrURL = SysAllocString(L"http://192.168.100.44/user.php"); IWebBrowser2_Navigate(pWebBrowser, bstrURL, &vEmpty, &vEmpty, &PostData, &Headers); // Wait for page to load do { LARGE_INTEGER TimeOut; UINT32 Milliseconds = 2000; TimeOut.QuadPart = UInt32x32To64( Milliseconds, 1000 ); TimeOut.QuadPart *= -1; NtDelayExecution(FALSE, &TimeOut); IWebBrowser2_get_Busy(pWebBrowser, &vBusy); } while(vBusy); // Get IDispatch interface IDispatch* pDispatch; IWebBrowser2_get_Document(pWebBrowser, &pDispatch); IHTMLDocument2* pDocument; IDispatch_QueryInterface(pDispatch, &IID_IHTMLDocument2 , &pDocument); IHTMLElement* lpBodyElm; IHTMLDocument2_get_body(pDocument, &lpBodyElm); IHTMLElement* lpParentElm; IHTMLElement_get_parentElement(lpBodyElm, &lpParentElm); // Get Inner HTML content content of the request BSTR bstrBody; lpParentElm->lpVtbl->get_innerHTML(lpParentElm, &bstrBody); wprintf(L"%ls\n\n", bstrBody); cleanup: SysFreeString(bstrURL); IWebBrowser2_Quit(pWebBrowser); IWebBrowser2_Release(pWebBrowser); IDispatch_Release(pDispatch); IHTMLDocument2_Release(pDocument); IHTMLElement_Release(lpBodyElm); lpParentElm->lpVtbl->Release(lpParentElm); CoUninitialize(); RtlExitUserProcess(STATUS_SUCCESS); }
问题根源及修复方案
1. VARIANT初始化错误
直接将LPSAFEARRAY赋值给VARIANT是错误的,必须正确设置VARIANT的类型标记:
VARIANT PostData; VariantInit(&PostData); PostData.vt = VT_ARRAY | VT_UI1; PostData.parray = FormularyArray;
2. HTTP头部格式错误
头部中的换行符应该是\r\n,且HTTP头部需要以空行结尾,修正后的头部:
V_BSTR(&Headers) = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n\r\n");
3. POST数据长度错误
sizeof(strFormulary)会包含字符串末尾的\0终止符,导致数据多一个字节,改用strlen获取实际长度:
size_t postLen = strlen(strFormulary); LPSAFEARRAY FormularyArray = SafeArrayCreateVector(VT_UI1, 0, postLen);
4. memcpy参数错误
数组名本身就是首地址,无需取地址,修正后的memcpy:
memcpy(pPostData, strFormulary, postLen);
修复后的关键代码片段
/* process the formulary data */ LPSTR pPostData = NULL; CHAR strFormulary[] = "sub=gt&name=sdfs"; size_t postLen = strlen(strFormulary); LPSAFEARRAY FormularyArray = SafeArrayCreateVector(VT_UI1, 0, postLen); VARIANT PostData; VariantInit(&PostData); PostData.vt = VT_ARRAY | VT_UI1; PostData.parray = FormularyArray; SafeArrayAccessData(FormularyArray, (LPVOID*)&pPostData); memcpy(pPostData, strFormulary, postLen); SafeArrayUnaccessData(FormularyArray); /* Set the headers data */ VARIANT Headers; VariantInit(&Headers); V_VT(&Headers) = VT_BSTR; V_BSTR(&Headers) = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n\r\n");
内容的提问来源于stack exchange,提问作者steve woods
相关产品推荐
相关产品推荐

