4.6 HTTPヘッダーを編集・設定する
HTTPヘッダーには、どこから来たのか(Referer)、何者なのか(User-Agent)、受信できるファイルはどれか(Accept)など、HTTPサーバと通信するときの(自分自身の)基礎情報(HTTPヘッダー)は、HttpAddRequestHeaders関数を使うと自在に設定できます。

参考までに、この技はAccess VBA以外に、Excelマクロなど他のVBAでも使用することができます。
API関数/HttpAddRequestHeadersを定義する
API関数を使うとき、まずはこの関数がどこにある・どんな関数であるかといった、この関数を使うための準備(API関数の宣言)が必要です。また、定義する場所はフォーム、モジュール、クラスモジュールの(General)(Declarations)です。

次の例は、API関数/HttpAddRequestHeadersを使うときの記述例です。API関数を使用するときは、ついでにAPI関数で使用する定数も定義しておきましょう。

'(General)(Declarations)へ記述します
Private Declare Function HttpAddRequestHeaders _
            Lib "wininet.dll" _
          Alias "HttpAddRequestHeadersA" _
         (ByVal hHttpRequest As Long _
        , ByVal sHeaders As String _
        , ByVal lHeadersLength As Long _
        , ByVal lModifiers As Long) As Integer

'lModifiers(ヘッダーの編集方法)
Public Const HTTP_ADDREQ_FLAG_ADD As Long     = &H20000000 '追加する
Public Const HTTP_ADDREQ_FLAG_REPLACE As Long = &H80000000 '置き換える
 ※決まり事なので、悩まずにコピペして使ってしまいましょう

この関数の戻り値には設定できたか、できなかったかが返ります。Trueが設定できた、Falseが設定できなかったを意味します。ただし、戻り値をCBool関数で変換してからTrue/Falseで判定しましょう。

 ◆HttpAddRequestHeadersの引数
ByVal hHttpRequest As Long HttpOpenRequestで取得したリクエストハンドルを指定します。
ByVal sHeaders As String 編集・設定するヘッダーの内容を指定します。HTTPヘッダーの例を参考にしてください。
ByVal lHeadersLength As Long sHeadersに設定したヘッダー情報の長さ(文字数)を指定します。
ByVal lModifiers As Long 追加(HTTP_ADDREQ_FLAG_ADD)または置き換え(HTTP_ADDREQ_FLAG_REPLACE)するかを指定します。
HTTPヘッダーを設定する例
HttpAddRequestHeadersでHTTPヘッダーを設定する例です。サンプルの内容は「4.2 HTTPサーバからの応答を取得する」をベースに、HTTPヘッダーの設定を追加する処理を加えています。

このサンプルでは、Referer(参照元)とUser-Agent(ブラウザのタイプ)の2種類を設定しました。設定するタイミングは、リクエストハンドル取得後です。

また、HTTPヘッダーの設定(HttpAddRequestHeadersの呼び出し)は、プロシージャ「fcHttpAddRequestHeaders」で行っています。HTTPヘッダーは、プロシージャを呼び出すときに引数で渡しています。

'変数の定義 ※(General)(Declarations)です
Private lngWinINet As Long 'インターネットハンドルの保存用
Private lngHttpHnd As Long 'HTTPハンドルの保存用
Private lngReqHnd  As Long 'HTTPリクエストハンドルの保存用
Private strBuffer  As String * 1024 'サーバからの応答保存用
Private lngLength  As Long '応答結果のデータ長


Sub prcHTTPQueryInfoSample()

    Dim lngRC As Long

    'インターネットサービスをオープンします
    lngRC = fcInternetOpen

    'オープンに成功したらHTTPサーバとの接続と切断を行います
    If lngRC = 0 Then

       'HTTPサーバへ接続します
       lngRC = fcHTTPConnect("www.uso-web-server.net")

       '接続に成功したらリクエストを初期化します
       If lngRC = 0 Then
          lngRC = fcHTTPOpenRequest("GET", "/cgi/test/get.cgi")
       End If

       'リクエストの初期化に成功したら、リクエストを送信します
       If lngRC = 0 Then
          Call fcHttpAddRequestHeaders("Referer: http://www.uso-server.net/")
          Call fcHttpAddRequestHeaders("User-Agent: Mozilla/4.0 (MSIE 999)")
          lngRC = fcHTTPSendRequest
       End If

       'サーバからの応答を取得します(サーバ情報を取得する例)
       If lngRC = 0 Then
          lngRC = fcHTTPQueryInfo(HTTP_QUERY_SERVER)
          MsgBox Left(strBuffer, lngLength)
       End If

       'HTTPリクエストをクローズします
       Call fcHttpRequestClose

       'HTTPサーバから切断します
       Call fcHTTPDisConnect

    End If

    'インターネットサービスをクローズします
    Call fcInternetClose

End Sub


Function fcHttpAddRequestHeaders(pHeader As String) As Long

    Dim lngRC As Long

    'APIの実行/ヘッダーを設定
    lngRC = HttpAddRequestHeaders(lngReqHnd _
                                , pHeader _
                                , Len(pHeader) _
                                , HTTP_ADDREQ_FLAG_REPLACE _
                               Or HTTP_ADDREQ_FLAG_ADD)

    'この関数の戻り値には、APIの戻り値を返します
    fcHTTPAddRequestHeaders = CBool(lngRC)

End Function


Function fcHTTPQueryInfo(lngInfoLevel As Long) As Long

    Dim tmpIndex As Long

    lngLength = 1024 '初期値はstrBufferの長さ
    strBuffer = vbNullString '受け取り領域は必ず初期化すること
    tmpIndex = 0

    'APIの実行/サーバからの応答を取得
    Call HttpQueryInfo(lngReqHnd _
                     , lngInfoLevel _
                     , ByVal strBuffer _
                     , lngLength _
                     , tmpIndex)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPQueryInfo = Err.LastDllError

End Function


Function fcHTTPSendRequest() As Long

    'APIの実行/リクエストを送信
    Call HttpSendRequest(lngReqHnd _
                       , vbNullString _
                       , 0 _
                       , vbNullString _
                       , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPSendRequest = Err.LastDllError

End Function


Function fcHTTPOpenRequest(strMethod As String, strURL As String) As Long

    Dim tmpURL    As String * 255

    'URLは255バイトの固定長文字列で渡す
    tmpURL = strURL

    'APIの実行/リクエストを初期化
    lngReqHnd = HttpOpenRequest(lngHttpHnd _
                              , strMethod _
                              , tmpURL _
                              , "HTTP/1.1" _
                              , vbNullString _
                              , 0 _
                              , INTERNET_FLAG_RELOAD _
                              , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPOpenRequest = Err.LastDllError

End Function


Function fcHttpRequestClose() As Long

    'APIの実行/インターネットサービスをクローズ
    Call InternetCloseHandle(lngReqHnd)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHttpRequestClose = Err.LastDllError

End Function


Function fcHTTPConnect(Server As String) As Long

    'APIの実行/HTTPサーバへ接続
    lngHttpHnd = InternetConnect(lngWinINet _
                              , Server _
                              , INTERNET_DEFAULT_HTTP_PORT _
                              , vbNullString _
                              , vbNullString _
                              , INTERNET_SERVICE_HTTP _
                              , 0 _
                              , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPConnect = Err.LastDllError

End Function


Function fcHTTPDisConnect() As Long

    'APIの実行/HTTPサーバから切断
    Call InternetCloseHandle(lngHttpHnd)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPDisConnect = Err.LastDllError

End Function


Function fcInternetOpen() As Long

    'APIの実行/インターネットサービスをオープン
    lngWinINet = InternetOpen(vbNullString _
                            , INTERNET_OPEN_TYPE_PRECONFIG _
                            , vbNullString _
                            , vbNullString _
                            , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcInternetOpen = Err.LastDllError

End Function


Function fcInternetClose() As Long

    'APIの実行/インターネットサービスをクローズ
    Call InternetCloseHandle(lngWinINet)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcInternetClose = Err.LastDllError

End Function
 ※この他に、API関数を定義する必要があります。
 ※www.uso-web-server.net、www.uso-server.netは架空のドメイン名です。
検証してみよう
実際にHTTPヘッダーが正しくセットされたかどうかは、パケットモニタというツールを使うと簡単に調べられます。パケットモニタはフリーソフトがいくつかありますが、おいらはMasa氏作のパケットモニターを使ってます。

では、まずはプログラムによるHTTPヘッダーの設定を行わなかった場合のパケットがどのようになっているかを見てみましょう。Hostなど、最低限必要なヘッダー情報が自動的に加えられているのが分かります。

 ◆HTTPヘッダー未設定のとき
GET./cgi/test/get.cgi.HTTP/1.1..Host:.www.uso-web-server.net..Cache-Control:.no-cache....

次に、HttpAddRequestHeadersを使いHTTPヘッダーを設定したときのパケットがどのようになっているかを見てみましょう。サンプルで設定したのはRefererとUser-Agentの2種類です。パケットを確認すると、この2種類が設定されていることがわかります。

 ◆RefererとUser-Agentを設定したとき
GET./cgi/test/get.cgi.HTTP/1.1..Referer:.http://www.uso-server.net/..User-Agent:.Mozilla/4.0.(MSIE.999)..Host:.www.uso-web-server.net..Cache-Control:.no-cache....
HTTPヘッダーの例
 以下はHTTPヘッダーの代表例です。必要に応じて設定します。なお、各ヘッダーの意味、設定できる内容については各自ググってくださいw

受け入れ可能な
ファイル種類
【書式】Accept: ファイル種類
【 例 】Accept: image/gif, image/x-xbitmap, image/jpeg, */*
受け入れ言語 【書式】Accept-Language: 受け入れ言語種類
【 例 】Accept-Language: ja,en-us
参照元 【書式】Referer: 参照元URL
【 例 】Referer: http://www.uso-server.net/search.cgi
受け入れ可能な
ファイルエンコード
【書式】Accept-Encoding: エンコード種類
【 例 】Accept-Encoding: gzip, deflate
ブラウザ種類 【書式】User-Agent: 参照元URL
【 例 】User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
参照先ホスト 【書式】Host: 参照先ホスト名
【 例 】Host: www.uso-server.net
HTTP接続方法 【書式】Connection: 接続方法
【 例 】Connection: Keep-Alive
クッキー 【書式】Cookie: クッキー情報
【 例 】Cookie: dta=gm%3D69%2Cmcg%3D90387%2Cmc3%3D3172986
Copyright(C) 1999-2006 結城圭介。 All rights reserved