利用IWebBrowser2接口的Navigate2方法實現Http POST傳輸
飄飄白云 2007/11/8
開發中的社區游戲,要求將原來的mini瀏覽器擴展成可以通過Http POST傳輸來打開網頁,比如:通過提交用戶id,password,用戶的action(查看profile,查看日記,打開blog等等),從而在mini瀏覽器里打開相應的網頁。
具體實現是通過獲取瀏覽器的IWebBrowser2指針,用該接口的Navigate2方法來實現,Navigate2在MSDN描述如下,
HRESULT Navigate2(
VARIANT *URL,
VARIANT *Flags,
VARIANT *TargetFrameName,
VARIANT *PostData,
VARIANT *Headers
);
具體參數細節請參看MSDN文檔。比較麻煩的是這個函數的參數設置,后面作詳細說明,先看代碼。這里有如下假定
iBrowser是一個有效的IWebBrowser2指針,
url為有效的地址(如:L"http://172.24.1.241/profile/"),
postData為需要提交的數據(
如:L"userid=kesalin&password=pwd&action=profile")
//飄飄白云(l_zhaohui@163.com) 2007/11/8
IWebBrowser2* iBrowser;
LPCTSTR url;
LPCTSTR postData
........//其他代碼
//Get size of Post Data
int size = WideCharToMultiByte(CP_ACP, 0, postData, -1, 0, 0, 0, 0);
VARIANT vURL;
VARIANT vFlags;
VARIANT vPostData;
VARIANT vHeaders;
VARIANT vNull;
// Init
VariantInit(&vURL);
VariantInit(&vFlags);
VariantInit(&vPostData);
VariantInit(&vHeaders);
VariantInit(&vNull);
// Set value
vHeaders.vt = VT_BSTR;
vHeaders.bstrVal = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n");
vFlags.vt = VT_I4;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
vURL.vt = VT_BSTR;
vURL.bstrVal = SysAllocString(url);
if (size > 1) {
// POST
char* pPostData = new char[size + 1];
WideCharToMultiByte(CP_ACP, 0, postData, -1, pPostData, size, 0, 0);
SAFEARRAY FAR* sfPost = NULL;
SAFEARRAYBOUND bound;
bound.cElements = (ULONG) (strlen(pPostData));
bound.lLbound = 0;
sfPost = SafeArrayCreate(VT_UI1, 1, &bound);
char* pChar = pPostData;
for (long lIndex = 0; lIndex < (signed)bound.cElements; lIndex++) {
SafeArrayPutElement(sfPost, &lIndex, (void*)((pChar++)));
}
vPostData.vt = VT_ARRAY | VT_UI1;
vPostData.parray = sfPost;
delete[] pPostData;
pPostData = NULL;
pChar = NULL;
iBrowser->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);
}
else {
// GET
iBrowser->Navigate2(&vURL, &vNull, &vNull, &vNull, &vNull);
}
// Clear
VariantClear(&vURL);
VariantClear(&vFlags);
VariantClear(&vPostData);
VariantClear(&vHeaders);
VariantClear(&vNull);
有三點值得說明:
第一, 數據類型 VT_I4 是指示一個long型的數據,所以要設置 VARIANT的lVal作為值。如代碼中的:
vFlags.vt = VT_I4;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
第二, 如果要實現POST數據提交,不能將Navigate2方法中不需要的參數簡單地設置成NULL,必須創建一個VARIANT變量vNull,并對它進行初始化。比如:
VariantInit(&vNull);
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
……
iBrowser->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);
第三, vPostData的變量類型是VT_ARRAY | VT_UI1,其數據是一個SAFEARRAY型的字符數組,具體賦值請參看代碼。