如何自动化IE的POST数据
我们可以通过VB或VC来调用自动化组件IE来进行POST操作,本文将说明如何利用IE控件完成此项工作。我们可以通过GET和POST两种方法向服务器发送数据,通常GET发送的数据不能超过2K,因此限制比较大。
IE支持IWebBrowser接口,此接口中有一个重要的函数Navigate,下面是它的IDL定义语法:
HRESULT Navigate([in] BSTR URL, [in] VARIANT* Flags,
[in] VARIANT* TargetFrameName, [in] VARIANT* PostData,
[in] VARIANT* Headers);
为了进行POST操作,只需要URL,PostData和Headers参数即可,其它参数请参阅MSDN中的Internet
Client SDK,为了向服务器发出数据,必须保证HTTP服务器地址正确,同时要保证PostData参数包括一个SAFEARRAY数据,
头必须包括BSTR,它包括:
Content-Type: application/x-www-form-urlencoded
此头说明了发送的数据是依什么编码进行编码的。
请将下面的ASP页保存在IIS服务器上。
<HTML>
<%
cFlavor = Request("Flavor")
cName = Request("FName")
%>
<BODY>
Hello, <% =cName %>. <br>
One scoop of <% =cFlavor %> coming right up!
</BODY>
</HTML>
Visual Basic
下面是在VB中使用POST,请建立一个标准EXE文件,Form1以按照默认情况创建,并将下列控件加入到form中:
Object Name Caption
-------------------------------------------------------------------
Label lblName First Name
Label lblFlavor Flavor
CommandButton cmdSubmit Submit
ComboBox cboFlavor
TextBox txtName
TextBox edtPostData
- 在“工程”中加入“引用”,选择"Microsoft Internet Controls"
(SHDOCVW.DLL)。
- 插入下面的代码:
Dim g_oIE As InternetExplorer 'Global reference to an instance of IE
Private Sub cmdSubmit_Click()
edtPostData.Text = "" ' Initialize an edit box for testing
ReDim aByte(0) As Byte ' Array of bytes to hold data to post
' Extract the URL encoded data from the UI, and pack it into an array of bytes
cFlavor = cboFlavor.List(cboFlavor.ListIndex)
cParamName = "FName="
cParamFlavor = "Flavor="
cSeparator = "&"
cPostData = cParamName & txtName.Text _
& cSeparator & cParamFlavor & cFlavor
PackBytes aByte(), cPostData
' For testing, rebuild the POST data and stuff it into an edit box
For i = LBound(aByte) To UBound(aByte)
edtPostData = edtPostData + Chr(aByte(i))
Next
Dim vPost As Variant
vPost = aByte ' Assign the byte array to a VARIANT
Dim vFlags As Variant
Dim vTarget As Variant
Dim vHeaders As Variant
vHeaders = _
"Content-Type: application/x-www-form-urlencoded" _
+ Chr(10) + Chr(13)
' You're done. Now call Navigate Note: modify path to server as appropriate
g_oIE.Navigate "http://<server>/scripts/navpost.asp", _
vFlags, vTarget, vPost, vHeaders
End Sub
Private Sub Form_Load()
' Create an instance of IE
Set g_oIE = New InternetExplorer
g_oIE.Visible = True
' Populate a combobox with some flavor choices
cboFlavor.List(0) = "Vanilla"
cboFlavor.List(1) = "Chocolate"
cboFlavor.List(2) = "Strawberry"
cboFlavor.ListIndex = 0 ' The default choice
End Sub
' Utility function to pack the data to post into an array of bytes
Private Sub PackBytes(ByteArray() As Byte, ByVal PostData As String)
iNewBytes = Len(PostData) - 1 ' Get rid of the null termination
If iNewBytes < 0 Then
Exit Sub
End If
ReDim ByteArray(iNewBytes)
For i = 0 To iNewBytes
ch = Mid(PostData, i + 1, 1)
If ch = Space(1) Then
ch = "+"
End If
ByteArray(i) = Asc(ch)
Next
End Sub
- 加入自己喜欢的URL,关闭所有的IE实例,运行此程序。
Visual C++
在VC++中就要多写一些代码了:
- 建立一个Win32控制台应用程序。
- 下面是具体代码:
#include <windows.h>
#define INITGUID
#include <initguid.h>
#include <exdisp.h>
#include <memory.h>
HRESULT GetPostData(LPVARIANT pvPostData);
void main()
{
HRESULT hr;
IWebBrowserApp* pWBApp = NULL; // Derived from IWebBrowser
BSTR bstrURL = NULL, bstrHeaders = NULL;
VARIANT vFlags = {0},
vTargetFrameName = {0},
vPostData = {0},
vHeaders = {0};
if (FAILED(hr = CoInitialize(NULL)))
{
return;
}
if (FAILED(hr = CoCreateInstance(CLSID_InternetExplorer,
NULL,
CLSCTX_SERVER,
IID_IWebBrowserApp,
(LPVOID*)&pWBApp)))
{
goto Error;
}
bstrURL = SysAllocString(L"http://<server>/scripts/navpost.asp");
if (!bstrURL)
{
goto Error;
}
bstrHeaders = SysAllocString(
L"Content-Type: application/x-www-form-urlencoded\r\n");
if (!bstrHeaders)
{
goto Error;
}
V_VT(&vHeaders) = VT_BSTR;
V_BSTR(&vHeaders) = bstrHeaders;
hr = GetPostData(&vPostData);
hr = pWBApp->Navigate(bstrURL, &vFlags,
&vTargetFrameName, &vPostData, &vHeaders);
pWBApp->put_Visible(VARIANT_TRUE);
Error:
if (bstrURL) SysFreeString(bstrURL);
if (bstrHeaders) SysFreeString(bstrHeaders);
VariantClear(&vPostData);
if (pWBApp) pWBApp->Release();
CoUninitialize();
}
// Pack some data into a SAFEARRAY of BYTEs. Return in a VARIANT
HRESULT GetPostData(LPVARIANT pvPostData)
{
HRESULT hr;
LPSAFEARRAY psa;
LPCTSTR cszPostData = "FName=Matt&Flavor=Mocha+Chip";
UINT cElems = lstrlen(cszPostData);
LPSTR pPostData;
if (!pvPostData)
{
return E_POINTER;
}
VariantInit(pvPostData);
psa = SafeArrayCreateVector(VT_UI1, 0, cElems);
if (!psa)
{
return E_OUTOFMEMORY;
}
hr = SafeArrayAccessData(psa, (LPVOID*)&pPostData);
memcpy(pPostData, cszPostData, cElems);
hr = SafeArrayUnaccessData(psa);
V_VT(pvPostData) = VT_ARRAY | VT_UI1;
V_ARRAY(pvPostData) = psa;
return NOERROR;
}
|