Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / System / Internet / HttpPost

HTML-Formulare mit VB ausfüllen

Einleitung

Problem

Soll ein Formular im Internet "ferngesteuert" werden, so sind i.A. die Übertragung umfangreicher Eingaben und die Nutzung der richtigen Übertragungsmethode (hier: "Post") nötig. Von Haus aus bietet VB da nur das sogenannte "Internet Transfer Control", welches einerseits die Installation des "Microsoft Internet Explorers" voraussetzt, und andererseits ziemlich Fehler-behaftet ist.

Mit der unten vorgestellten HttpPost-Funktion ist es nun möglich, ohne Extra-Control HTML-Formulare "auszufüllen" und die Ergebnisse des Absendens abzufragen. So können dann auch VB-Anwendungen interaktive (dynamische) Ressourcen im Internet nutzen.

Übrigens: Sollen dagegen nur statische Seiten "downgeloadet" werden, genügt das in "HTML-Quelltext aus URL lesen" gezeigte, einfachere Verfahren.

Beispiel

Im folgende Beispiel wird ein HTML-Formular mit drei Eingabefeldern (seien die Namen einfach "X", "Y" und "Z") ausgefüllt (ein Text mit Zeilenumbruch, eine Zahl, sowie ein Text mit Sonderzeichen). Das Ergebnis wird anschließend in einer MsgBox angezeigt.

Sub Test
  Const URL = "http://127.0.0.1/showdata.asp"
  Dim x As String
  Dim y As String
  Dim z As String
  Dim s As String
  
  'Text mit Zeilenumbruch:
  x = "Dies ist eine Zeile." & vbNewLine & "Noch eine Zeile!"
  x = URLEncode(x)

  'einfache Zahl:
  y = CStr(42)
  y = URLEncode(y) 'in diesem Fall nicht nötig

  'Text mit Sonderzeichen:
  z = "Sonderzeichen: ""äöüß&="
  z = URLEncode(z)

  s = HttpPost(URL, "X=" & x & "&Y=" & y & "&Z=" & z)
  MsgBox s
End Sub

Man beachte, wie eventuelle Sonderzeichen (insbesondere "=" und "&") durch Einsatz der in "Codieren von Strings fürs Web" gezeigten URLEncode-Funktion umgesetzt werden, so dass es beim Ziel-Server entsprechende Verständnis-Probleme vermieden werden.

Code / Quelltext

API-Deklarationen (Internet allgemein)

Im Deklarationsteil eines Formulars oder (besser) Standardmoduls müssen folgende API-Funktionen aus der wininet-Bibliothek bekannt gemacht werden:

Private Declare Function InternetCloseHandle Lib "wininet.dll" ( _
    ByVal hInternetHandle As Long) As Boolean
Private Declare Function InternetConnectA Lib "wininet.dll" ( _
    ByVal hInternetSession As Long, ByVal lpszServerName As String, _
    ByVal nProxyPort As Integer, ByVal lpszUsername As String, _
    ByVal lpszPassword As String, ByVal dwService As Long, _
    ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function InternetOpenA Lib "wininet.dll" ( _
    ByVal lpszCallerName As String, ByVal dwAccessType As Long, _
    ByVal lpszProxyName As String, ByVal lpszProxyBypass As String, _
    ByVal dwFlags As Long) As Long
Private Declare Function InternetReadFile Lib "wininet.dll" ( _
    ByVal hFile As Long, ByVal sBuffer As String, _
    ByVal lNumBytesToRead As Long, Bytes As Long _
  ) As Integer
Private Const INTERNET_FLAG_RELOAD = &H80000000
Private Const INTERNET_SERVICE_HTTP = 3

API-Deklarationen (HTTP)

Ebenso werden (an gleicher Stelle) folgende API-Funktionen für HTTP (ein bestimmtes Protokoll zur Übertragung von Internet-Seiten) benötigt:

Private Declare Function HttpAddRequestHeadersA Lib "wininet.dll" ( _
    ByVal hHttpRequest As Long, ByVal sHeaders As String, _
    ByVal lHeadersLength As Long, _
    ByVal lModifiers As Long) As Integer
Private Declare Function HttpOpenRequestA Lib "wininet.dll" ( _
    ByVal hInternetSession As Long, ByVal lpszVerb As String, _
    ByVal lpszObjectName As String, ByVal lpszVersion As String, _
    ByVal lpszReferer As String, ByVal lpszAcceptTypes As Long, _
    ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function HttpSendRequestA Lib "wininet.dll" ( _
    ByVal hHttpRequest As Long, ByVal sHeaders As String, _
    ByVal lHeadersLength As Long, ByVal sOptional As String, _
    ByVal lOptionalLength As Long) As Boolean
Private Const HTTP_ADDREQ_FLAG_ADD = &H20000000
Private Const HTTP_ADDREQ_FLAG_REPLACE = &H80000000

Sonstige Deklarationen

Der folgende Code-Abschnitt gehört ebenfalls in die Deklarationen. Die Enumeration/Aufzählung InternetOpenType dient übrigens zur Festlegung, wie die Internet-Verbindung geöffnet werden soll (Voreinstellung, Direkt oder via Proxy).

'Anwendungs-spezifisches:
Private Const INET_CallerName = "VB-Tec:INET"
Private Const INET_ContentType = _
    "Content-Type: application/x-www-form-urlencoded" & vbCrLf

'Enumeration für Internet:
Public Enum InternetOpenType
  IOTPreconfig = 0
  IOTDirect = 1
  IOTProxy = 3
End Enum

Funktion HttpPost

Die eigentliche Arbeit geschieht in folgender Funktion: Zuerst wird aus der angegebenen URL der Name des Servers und der "Dateipfad" ausgeschnitten. Dann wird eine Internet-Verbindung geöffnet, sowie die Header-Daten (sprich: Formular-Eingabedaten) geschrieben. Anschließend werden solange Rückgabedaten gesammelt, bis keine mehr da sind. Am Ende werden alle benutzen Ressourcen wieder freigegeben.

Public Function HttpPost( _
    ByVal URL As String, _
    Optional ByRef Data As String, _
    Optional ByVal OpenType As InternetOpenType = IOTPreconfig, _
    Optional ByVal Port As Integer = 80, _
    Optional ByVal Username As String, _
    Optional ByVal Password As String _
  ) As String
  Dim Server As String
  Dim Path As String
  Dim hOpen As Long
  Dim hConnect As Long
  Dim hRequest As Long
  Dim Buffer As String * 2048
  Dim Bytes  As Long
  Dim i As Long
  
  'Server und Pfad bestimmen:
  URL = Trim$(URL)
  If LCase$(Left$(URL, 7)) = "http://" Then _
      URL = Mid$(URL, 8)
  i = InStr(URL, "/")
  If i > 0 Then
    'Server und Pfad trennen:
    Server = Left$(URL, i - 1)
    Path = Mid$(URL, i)
  Else
    'Root-Pfad verwenden:
    Server = URL
    Path = "/"
  End If
  
  'Internet-Handles öffnen:
  hOpen = InternetOpenA( _
      INET_CallerName, OpenType, _
      vbNullString, vbNullString, 0)
  hConnect = InternetConnectA( _
      hOpen, Server, Port, Username, Password, _
      INTERNET_SERVICE_HTTP, 0, 0)
  hRequest = HttpOpenRequestA( _
      hConnect, "POST", Path, "HTTP/1.0", _
      vbNullString, 0, INTERNET_FLAG_RELOAD, 0)
  
  'Header (mitsamt Daten) senden:
  HttpAddRequestHeadersA _
      hRequest, INET_ContentType, Len(INET_ContentType), _
      HTTP_ADDREQ_FLAG_REPLACE Or HTTP_ADDREQ_FLAG_ADD
  HttpSendRequestA _
      hRequest, vbNullString, 0, Data, Len(Data)
  
  'Ergebnis-Daten sammeln:
  Do
    InternetReadFile hRequest, Buffer, Len(Buffer), Bytes
    If Bytes = 0 Then Exit Do
    HttpPost = HttpPost & Left$(Buffer, Bytes)
  Loop
  
  'Internet-Handles schließen:
  InternetCloseHandle hRequest
  InternetCloseHandle hConnect
  InternetCloseHandle hOpen
End Function

© Jost Schwider, 21.06.2001-21.06.2001 - http://vb-tec.de/httppost.htm