共用方式為


HTTP 會話

WinINet 可讓您存取萬維網 (WWW) 上的資源。 您可以使用 InternetOpenUrl 直接存取這些資源(如需詳細資訊,請參閱 直接存取 URL)。

WWW 上的資源是使用 HTTP 來存取。 HTTP 函式會處理基礎通訊協定,同時允許您的應用程式存取 WWW 上的資訊。 隨著 HTTP 通訊協定的發展,基礎通訊協定會更新以維護函式行為。

下圖顯示與 HTTP 通訊協定搭配使用的函式關聯性。 陰影方塊代表傳回 HINTERNET 句柄的函式,而純文本方塊則代表使用函式所建立之函式 HINTERNET 句柄。

用於 HTTP 的 wininet 函式

如需詳細資訊,請參閱 HINTERNET 句柄

使用 WinINet 函式存取 WWW

HTTP 會話期間會使用下列函式來存取 WWW。

功能 描述
HttpAddRequestHeaders 將 HTTP 要求標頭新增至 HTTP 要求句柄。 此函式需要由 HttpOpenRequest所建立的句柄。
HttpOpenRequest 開啟 HTTP 要求句柄。 此函式需要由 InternetConnect所建立的句柄。
HttpQueryInfo 查詢 HTTP 要求的相關信息。 此函式需要由 HttpOpenRequestInternetOpenUrl 函式所建立的句柄。
HttpSendRequest 將指定的 HTTP 要求傳送至 HTTP 伺服器。 此函式需要由 HttpOpenRequest所建立的句柄。
InternetErrorDlg 顯示常見因特網錯誤狀況的預先定義對話框。 此函式需要呼叫中所使用的句柄,才能 HttpSendRequest

 

起始 WWW 的連線

若要開始與 WWW 的連線,應用程式必須在 internetOpen回的根 HINTERNET 上呼叫 InternetConnect 函式。 InternetConnect 必須藉由宣告INTERNET_SERVICE_HTTP服務類型來建立 HTTP 工作階段。 如需使用 InternetConnect的詳細資訊,請參閱使用 InternetConnect

開啟要求

HttpOpenRequest 函式會開啟 HTTP 要求,並傳回其他 HTTP 函式可以使用的 HINTERNET 句柄。 不同於其他開啟函式(例如 FtpOpenFileInternetOpenUrl),HttpOpenRequest 不會在呼叫時將要求傳送至因特網。 HttpSendRequest 函式會傳送要求,並透過網路建立連線。

HttpOpenRequest 接受由 InternetConnect 和 HTTP 動詞、物件名稱、版本字串、查閱者、接受類型、旗標和內容值所建立的 HTTP 會話句柄。

HTTP 動詞命令是在要求中使用的字串。 要求中使用的常見 HTTP 動詞包括 GET、PUT 和 POST。 如果此值設定為 NULLHttpOpenRequest 會使用預設值 GET。

物件名稱是包含指定 HTTP 動詞目標物件名稱的字串。 這通常是檔名、可執行模組或搜尋規範。 如果提供的物件名稱是空字串,HttpOpenRequest 會尋找預設頁面。

版本字串應該包含 HTTP 版本。 如果此參數 NULL,則函式會使用 “”HTTP/1.1“。

查閱者會指定從中取得物件名稱的檔案位址。 如果此參數 NULL,則未指定任何查閱者。

null終止字串,其中包含接受型別,表示應用程式接受的內容類型。 將此參數設定為 NULL 表示應用程式不接受任何內容類型。 如果提供空字串,應用程式會指出它只接受 「text/*」 類型的檔。 值 「text/*」 表示純文字檔,而不是圖片或其他二進位檔。

旗標值會控制快取、Cookie 和安全性問題。 針對Microsoft網路 (MSN)、NTLM 和其他類型的驗證,請設定 INTERNET_FLAG_KEEP_CONNECTION 旗標。

如果在呼叫 InternetOpen中設定了 INTERNET_FLAG_ASYNC 旗標,則應該為適當的異步作設定非零內容值。

下列範例是 HttpOpenRequest的範例呼叫。

hHttpRequest = HttpOpenRequest( hHttpSession, "GET", "", NULL, "", NULL, 0, 0);

新增要求標頭

HttpAddRequestHeaders 函式可讓應用程式將一或多個要求標頭新增至初始要求。 此函式可讓應用程式將額外的自由格式標頭附加至 HTTP 要求句柄;它適用於需要精確控制傳送至 HTTP 伺服器之要求的複雜應用程式。

HttpAddRequestHeaders 需要由 HttpOpenRequest所建立的 HTTP 要求句柄、包含標頭、標頭長度和修飾詞的字元串。

傳送要求

HttpSendRequest 會建立因特網的連線,並將要求傳送至指定的網站。 此函式需要由 HttpOpenRequest所建立 HINTERNET 句柄。 HttpSendRequest 也可以傳送其他標頭或選擇性資訊。 選擇性資訊通常用於將資訊寫入伺服器的作業,例如 PUT 和 POST。

HttpSendRequest 傳送要求之後,應用程式可以使用 InternetReadFileInternetQueryDataAvailable,以及 InternetSetFilePointer 函式 HINTERNET 句柄,HttpOpenRequest 來下載伺服器的資源。

將數據張貼至伺服器

若要將數據張貼至伺服器,呼叫中的 HTTP 動詞 HttpOpenRequest 必須是 POST 或 PUT。 然後,包含 POST 數據的緩衝區地址應該傳遞至 HttpSendRequest中的 lpOptional 參數。 dwOptionalLength 參數應設定為數據的大小。

您也可以使用 InternetWriteFile 函式,在使用 HTTPSendRequestEx傳送的 HINTERNET 句柄上張貼數據。

取得要求的相關信息

HttpQueryInfo 可讓應用程式擷取 HTTP 要求的相關信息。 函式需要由 HttpOpenRequestInternetOpenUrl、資訊層級值和緩衝區長度所建立 HINTERNET 句柄。 HttpQueryInfo 也接受儲存資訊的緩衝區,以及列舉同名多個標頭的以零起始的標頭索引。

從 WWW 下載資源

使用 HttpOpenRequest 開啟要求並將其傳送至具有 HttpSendRequest的伺服器之後,應用程式可以使用 InternetReadFileInternetQueryDataAvailable,以及 InternetSetFilePointer 函式,從 HTTP 伺服器下載資源。

下列範例會下載資源。 函式會接受目前視窗的句柄、編輯框的標識符,以及由 HttpOpenRequest 所建立的 HINTERNET 句柄,並由 HttpSendRequest傳送。 它會使用 InternetQueryDataAvailable 來判斷資源的大小,然後使用 InternetReadFile下載它。 內容接著會顯示在編輯框中。

int WINAPI Dumper(HWND hX, int intCtrlID, HINTERNET hResource)
{
    LPTSTR lpszData;    // buffer for the data
    DWORD  dwSize;       // size of the data available
    DWORD  dwDownloaded; // size of the downloaded data
    DWORD  dwSizeSum=0;  // size of the data in the textbox
    LPTSTR lpszHolding;  // buffer to merge the textbox data and buffer

    // Set the cursor to an hourglass.
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    // This loop handles reading the data.
    do
    {
        // The call to InternetQueryDataAvailable determines the
        // amount of data available to download.
        if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))
        {
            printf("InternetQueryDataAvailable failed (%d)\n", GetLastError());
            SetCursor(LoadCursor(NULL,IDC_ARROW));
            return FALSE;
        }
        else
        {
            // Allocate a buffer of the size returned by
            // InternetQueryDataAvailable.
            lpszData = new TCHAR[dwSize+1];

            // Read the data from the HINTERNET handle.
            if(!InternetReadFile(hResource,
                                 (LPVOID)lpszData,
                                 dwSize,
                                 &dwDownloaded))
            {
                printf("InternetReadFile failed (%d)\n", GetLastError());
                delete[] lpszData;
                break;
            }
            else
            {
                // Add a null terminator to the end of the data buffer
                lpszData[dwDownloaded]='\0';

                // Allocate the holding buffer.
                lpszHolding = new TCHAR[dwSizeSum + dwDownloaded + 1];

                // Check if there has been any data written
                // to the textbox.
                if (dwSizeSum != 0)
                {
                    // Retrieve the data stored in the textbox if any
                    GetDlgItemText(hX,intCtrlID,
                                   (LPTSTR)lpszHolding,
                                   dwSizeSum);

                    // Add a null terminator at the end of the
                    // textbox data.
                    lpszHolding[dwSizeSum]='\0';
                }
                else
                {
                    // Make the holding buffer an empty string.
                    lpszHolding[0]='\0';
                }

                size_t cchDest = dwSizeSum + dwDownloaded + dwDownloaded + 1;
                LPTSTR* ppszDestEnd = 0;
                size_t* pcchRemaining = 0;

                // Add the new data to the holding buffer
                HRESULT hr = StringCchCatEx(lpszHolding,
                                            cchDest,
                                            lpszData,
                                            ppszDestEnd,
                                            pcchRemaining,
                                            STRSAFE_NO_TRUNCATION);

                if(SUCCEEDED(hr))
                {
                    // Write the holding buffer to the textbox.
                    SetDlgItemText(hX,intCtrlID,(LPTSTR)lpszHolding);

                    // Delete the two buffers.
                    delete[] lpszHolding;
                    delete[] lpszData;

                    // Add the size of the downloaded data to the
                    // textbox data size.
                    dwSizeSum = dwSizeSum + dwDownloaded + 1;

                    // Check the size of the remaining data.
                    // If it is zero, break.
                    if (dwDownloaded == 0)
                        break;
                    else
                    {
                    //  TODO: Insert error handling code here.
                    }
                }
            }
        }
    }
    while(TRUE);

    // Close the HINTERNET handle.
    InternetCloseHandle(hResource);

    // Set the cursor back to an arrow.
    SetCursor(LoadCursor(NULL,IDC_ARROW));

    return TRUE;
}

注意

WinINet 不支援伺服器實作。 此外,不應該從服務使用。 針對伺服器實作或服務,請使用 Microsoft Windows HTTP 服務 (WinHTTP)