HTTP 會話
WinINet 可讓您存取 World Wide Web (WWW) 上的資源。 如需詳細資訊,您可以使用 InternetOpenUrl (直接存取這些資源,請參閱 直接存取 URL) 。
WWW 上的資源是使用 HTTP 來存取。 HTTP 函式會處理基礎通訊協定,同時允許您的應用程式存取 WWW 上的資訊。 隨著 HTTP 通訊協定演進,基礎通訊協定會更新以維護函式行為。
下圖顯示與 HTTP 通訊協定搭配使用的函式關聯性。 陰影方塊代表傳回 HINTERNET 控制碼的函式,而純方塊則代表使用函式所建立 之 HINTERNET 控制碼的函式。
如需詳細資訊,請參閱 HINTERNET 控制碼。
使用 WinINet 函式存取 WWW
HTTP 會話期間會使用下列函式來存取 WWW。
函式 | 描述 |
---|---|
HttpAddRequestHeaders | 將 HTTP 要求標頭新增至 HTTP 要求控制碼。 此函式需要 由 HttpOpenRequest建立的控制碼。 |
HttpOpenRequest | 開啟 HTTP 要求控制碼。 此函式需要 InternetConnect所建立的控制碼。 |
HttpQueryInfo | 查詢 HTTP 要求的相關資訊。 此函式需要 HttpOpenRequest 或 InternetOpenUrl 函式所建立的控制碼。 |
HttpSendRequest | 將指定的 HTTP 要求傳送至 HTTP 伺服器。 此函式需要 由 HttpOpenRequest建立的控制碼。 |
InternetErrorDlg | 顯示常見網際網路錯誤狀況的預先定義對話方塊。 此函式需要 HttpSendRequest呼叫中使用的控制碼。 |
起始 WWW 的連線
若要啟動與 WWW 的連線,應用程式必須在InternetOpen所傳回的根HINTERNET上呼叫InternetConnect函式。 InternetConnect 必須宣告INTERNET_SERVICE_HTTP服務類型來建立 HTTP 會話。 如需使用 InternetConnect的詳細資訊,請參閱 使用 InternetConnect。
開啟要求
HttpOpenRequest函式會開啟 HTTP 要求,並傳回可供其他 HTTP 函式使用的HINTERNET控制碼。 不同于其他開啟函式 (,例如 FtpOpenFile 和 InternetOpenUrl) , HttpOpenRequest 不會在呼叫時將要求傳送至網際網路。 HttpSendRequest函式會傳送要求,並透過網路建立連線。
HttpOpenRequest 接受 由 InternetConnect 和 HTTP 動詞、物件名稱、版本字串、查閱者、接受類型、旗標和內容值所建立的 HTTP 會話控制碼。
HTTP 動詞命令是在要求中使用的字串。 要求中使用的常見 HTTP 動詞命令包括 GET、PUT 和 POST。 如果此值設定為 Null, HttpOpenRequest 會使用預設值 GET。
物件名稱是包含指定 HTTP 動詞目標物件名稱的字串。 這通常是檔案名、可執行模組或搜尋規範。 如果提供的物件名稱是空字串, HttpOpenRequest 會尋找預設頁面。
版本字串應該包含 HTTP 版本。 如果此參數為 Null,此函式會使用 「」HTTP/1.1」。
查閱者會指定從中取得物件名稱的檔位址。 如果此參數為 Null,則不會指定任何參考者。
包含接受類型的 Null終止字串表示應用程式所接受的內容類型。 將此參數設定為 Null 表示應用程式不接受任何內容類型。 如果提供空字串,應用程式會指出它只接受 「」text/*「 類型的檔。 值 「」text/*「」 表示純文字檔,而非圖片或其他二進位檔案。
旗標值可控制快取、Cookie 和安全性問題。 針對 Microsoft Network (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傳送要求之後,應用程式可以使用HttpOpenRequest所建立之 HINTERNET控制碼上的InternetReadFile、InternetQueryDataAvailable和InternetSetFilePointer函式來下載伺服器的資源。
將資料張貼到伺服器
若要將資料張貼到伺服器, 呼叫 HttpOpenRequest 中的 HTTP 動詞命令必須是 POST 或 PUT。 接著,包含 POST 資料的緩衝區位址應該會傳遞至HttpSendRequest中的lpOptional參數。 dwOptionalLength參數應該設定為數據的大小。
您也可以使用InternetWriteFile函式,在使用HttpSendRequestEx傳送的HINTERNET控制碼上張貼資料。
取得要求的相關資訊
HttpQueryInfo 可讓應用程式擷取 HTTP 要求的相關資訊。 函式需要HttpOpenRequest或InternetOpenUrl所建立的HINTERNET控制碼、資訊層級值和緩衝區長度。 HttpQueryInfo 也接受儲存資訊的緩衝區,以及以零起始的標頭索引,列舉具有相同名稱的多個標頭。
從 WWW 下載資源
使用 HttpOpenRequest 開啟要求並將它傳送至具有 HttpSendRequest的伺服器之後,應用程式可以使用 InternetReadFile、 InternetQueryDataAvailable和 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 Services (WinHTTP) 。