利用
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 文档。比较麻烦的是这个函数的参数设置,后面作详细说明,先看代码。这里有如下假定
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;
LPCTSTR url;
LPCTSTR postData;
// .......other codes.
//Get size of Post Data
int size = WideCharToMultiByte(CP_ACP, 0, postData, -1, 0, 0, 0, 0);
int size = WideCharToMultiByte(CP_ACP, 0, postData, -1, 0, 0, 0, 0);
VARIANT vURL;
VARIANT vFlags;
VARIANT vPostData;
VARIANT vHeaders;
VARIANT vNull;
VARIANT vFlags;
VARIANT vPostData;
VARIANT vHeaders;
VARIANT vNull;
// Init
VariantInit(&vURL);
VariantInit(&vFlags);
VariantInit(&vPostData);
VariantInit(&vHeaders);
VariantInit(&vNull);
VariantInit(&vURL);
VariantInit(&vFlags);
VariantInit(&vPostData);
VariantInit(&vHeaders);
VariantInit(&vNull);
// Set value
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
vHeaders.vt = VT_BSTR;
vHeaders.bstrVal = SysAllocString(L"Content-Type: application/x-www-form-urlencoded/r/n");
vHeaders.bstrVal = SysAllocString(L"Content-Type: application/x-www-form-urlencoded/r/n");
vFlags.vt = VT_I4;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
vURL.vt = VT_BSTR;
vURL.bstrVal = SysAllocString(url);
vURL.bstrVal = SysAllocString(url);
if (size > 1) {
// POST
char* pPostData = new char[size + 1];
WideCharToMultiByte(CP_ACP, 0, postData, -1, pPostData, size, 0, 0);
// 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);
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++)));
}
for (long lIndex = 0; lIndex < (signed)bound.cElements; lIndex++) {
SafeArrayPutElement(sfPost, &lIndex, (void*)((pChar++)));
}
vPostData.vt = VT_ARRAY | VT_UI1;
vPostData.parray = sfPost;
vPostData.parray = sfPost;
SafeArrayDestroy(sfPost);
delete[] pPostData;
pPostData = NULL;
pChar = NULL;
delete[] pPostData;
pPostData = NULL;
pChar = NULL;
iBrowser->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);
}
else {
// GET
iBrowser->Navigate2(&vURL, &vNull, &vNull, &vNull, &vNull);
}
}
else {
// GET
iBrowser->Navigate2(&vURL, &vNull, &vNull, &vNull, &vNull);
}
// Clear
VariantClear(&vURL);
VariantClear(&vFlags);
VariantClear(&vPostData);
VariantClear(&vHeaders);
VariantClear(&vNull);
VariantClear(&vURL);
VariantClear(&vFlags);
VariantClear(&vPostData);
VariantClear(&vHeaders);
VariantClear(&vNull);
有三点值得说明:
第一,
数据类型
VT_I4
是指示一个
long
型的数据,所以要设置
VARIANT
的
lVal
作为值。如代码中的:
vFlags.vt = VT_I4;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
第二,
如果要实现
POST
数据提交,不能将
Navigate2
方法中不需要的参数简单地设置成
NULL
,必须创建一个
VARIANT
变量
vNull
,并对它进行初始化。比如:
VariantInit(&vNull);
第三,
vPostData
的变量类型是
VT_ARRAY
| VT_UI1
,其数据是一个
SAFEARRAY
型的字符数组,具体赋值请参看代码。
// Set value
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
iBrowser->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);