How To Automate Internet Explorer to POST Form Data

Exención de responsabilidades de contenido KB retirado

Este artículo se refiere a productos para los que Microsoft ya no ofrece soporte técnico. Por tanto, el presente artículo se ofrece "tal cual" y no será actualizado.

Summary

An automation controller such as Microsoft Visual Basic can automate Internet Explorer (IE) to send data using the POST method to an HTTP server such as Internet Information Server (IIS). This article demonstrates how to automate IE to perform a POST of form data from Visual Basic and from a simple Visual C++ application. While the examples illustrate automation of the whole Internet Explorer application, the same techniques can be applied to the Web Browser ActiveX control when it is hosted in an application.

More Information

Several methods are available for sending data to an HTTP server. GET and POST are currently the most common. POST is typically used to submit form data to an HTTP server when that data exceeds the maximum allowable transfer using the GET method. This limit is typically 2K.

IE exposes the IWebBrowser(App) interface to automation controllers. The IWebBrowser(App) interface exposes a Navigate method. In interface definition language (IDL) syntax (a universal representation from which both the Visual Basic and Visual C++ syntax is derived), the Navigate method looks like the following:
HRESULT Navigate([in] BSTR URL, [in] VARIANT* Flags,
[in] VARIANT* TargetFrameName, [in] VARIANT* PostData,
[in] VARIANT* Headers);
For the purposes of performing a POST, only the URL, PostData, and Headers parameters are relevant. See the Internet Client SDK documentation for information on the other parameters.

To call Navigate and POST form data to an HTTP server, the URL parameter must specify a valid address, the PostData parameter must contain a SAFEARRAY of bytes, and the Headers parameter must contain a BSTR that contains the following HTTP header:
Content-Type: application/x-www-form-urlencoded
This header indicates that the data being posted is encoded according to the rules specified in the HTML specification.

Internet Explorer versions 3.0, 3.01, and 3.02 do not support posting data to an HTTP server via the Navigate method. WinInet and URL Monikers are two possible alternatives. For more information on WinInet and Monikers, see the REFERENCES section of this article.


Note that the Internet Explorer Script Object Model object "window" has a "navigate" method as well. This navigate method will only accept a URL and cannot be used to POST data to a web server.


To test the examples below, the following Active Server Page (ASP) should be saved to the file NAVPOST.ASP in a directory on an NT 4.0 server running Internet Information Server (IIS) version 3.0. The directory should be recognized by IIS as a virtual root with execute permission:
   <HTML>
<%
cFlavor = Request("Flavor")
cName = Request("FName")
%>
<BODY>
Hello, <% =cName %>. <br>
One scoop of <% =cFlavor %> coming right up!
</BODY>
</HTML>

Visual Basic

To demonstrate a POST in Visual Basic, perform the following steps:

  1. Start a new Standard EXE project in Visual Basic. Form1 is created by default. Add the following controls to Form1:

    Object Name Caption
    -------------------------------------------------------------------

    Label lblName First Name
    Label lblFlavor Flavor
    CommandButton cmdSubmit Submit

    ComboBox cboFlavor
    TextBox txtName
    TextBox edtPostData
    (edtPostData should be multi-line and have scroll bars)
  2. Invoke "References" from the Project menu and add a reference to the project for "Microsoft Internet Controls" (SHDOCVW.DLL). Make sure this is done from the References dialog and not just from the Components dialog.
  3. Insert the following code in the General Declarations section:
          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
  4. Modify the URL in the call to Navigate as appropriate, close all running instance of IE, and choose Start from the Run menu.
  5. Enter your name in the first name textbox, choose a flavor, and click the Submit command button. The data from the Visual Basic form will be posted to the HTTP server and the response will appear in the visible browser window.

Visual C++

To demonstrate a POST in Visual C++, perform the following steps:


  1. Ensure that the ActiveX or Internet Client SDK is installed.
  2. Launch Visual C++, and create a new Win32 console project.
  3. Create a new text document, and add the following code:
          #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;
    }
  4. Modify the URL reference as appropriate, and save the code. Add it to the project, and then build.
  5. Close all browser instances and run the application.
  6. Switch to the running instance of IE to see that the data was posted.

References

For a Microsoft Visual Basic .NET version of this article, see
311293 .
Berners-Lee, T. RFC 1866. "Hypertext Markup Language - 2.0." Internet Client SDK documentation

For more information on how to use WinInet to simulate a form POST request, please refer to the following article in the Microsoft Knowledge Base:
165298 How To Simulate a Form POST Request Using WinInet
For more information on how to use a URL Moniker to simulate a form POST request, please refer to the following article in the Microsoft Knowledge Base:
165800 SAMPLE: Using a URL Moniker to POST Data
Propiedades

Id. de artículo: 167658 - Última revisión: 06/22/2014 - Revisión: 1

Comentarios