winHttpSendRequest 函式 (winHTTP.h)
WinHttpSendRequest 函式會將指定的要求傳送至 HTTP 伺服器。
語法
WINHTTPAPI BOOL WinHttpSendRequest(
[in] HINTERNET hRequest,
[in, optional] LPCWSTR lpszHeaders,
[in] DWORD dwHeadersLength,
[in, optional] LPVOID lpOptional,
[in] DWORD dwOptionalLength,
[in] DWORD dwTotalLength,
[in] DWORD_PTR dwContext
);
參數
[in] hRequest
WinHttpOpenRequest 傳回的 HINTERNET 句柄。
[in, optional] lpszHeaders
字串的指標,其中包含要附加至要求的其他標頭。 如果沒有附加其他標頭 ,則可以WINHTTP_NO_ADDITIONAL_HEADERS 此參數。
[in] dwHeadersLength
不帶正負號的長整數值,其中包含其他標頭的長度,以字元為單位。 如果此參數為 -1L 且 pwszHeaders 不是 NULL,則此函式會假設 pwszHeaders 為 null 終止,並計算長度。
[in, optional] lpOptional
緩衝區的指標,其中包含要在要求標頭之後立即傳送的任何選擇性數據。 此參數通常用於 POST 和 PUT 作業。 選擇性數據可以是張貼至伺服器的資源或數據。 如果沒有選擇性的數據可供傳送 ,則可以WINHTTP_NO_REQUEST_DATA 此參數。
如果 dwOptionalLength 參數為 0,則會忽略此參數並設定為 NULL。
此緩衝區必須保持可用狀態,直到要求句柄關閉或 WinHttpReceiveResponse 的呼叫完成為止。
[in] dwOptionalLength
不帶正負號的長整數值,其中包含選擇性數據的長度,以位元組為單位。 如果沒有選擇性數據要傳送,此參數可以是零。
當 lpOptional 參數不是 NULL 時,此參數必須包含有效的長度。 否則會忽略 lpOptional ,並將 設定為 NULL。
[in] dwTotalLength
不帶正負號的長整數值,包含傳送之數據總數的長度,以位元組為單位。 此參數會指定要求的 Content-Length 標頭。 如果此參數的值大於 dwOptionalLength 所指定的長度,則可以使用 WinHttpWriteData 來傳送其他數據。
dwTotalLength 在呼叫 WinHttpSendRequest 時不得變更相同的要求。 如果需要變更 dwTotalLength ,呼叫端應該建立新的要求。
[in] dwContext
指標大小變數的指標,其中包含透過要求句柄傳遞至任何回呼函式的應用程式定義值。
傳回值
如果成功,則傳回 TRUE ,否則傳回 FALSE 。 如需擴充錯誤資訊,請呼叫 GetLastError。 下表列出錯誤碼。
錯誤碼 | 描述 |
---|---|
|
如果與伺服器的連線失敗,則傳回 。 |
|
安全 HTTP 伺服器需要客戶端憑證。 應用程式會使用 WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST 選項呼叫 WinHttpQueryOption 來擷取憑證簽發者清單。
如果伺服器要求客戶端憑證,但不需要它,應用程式可以使用 WINHTTP_OPTION_CLIENT_CERT_CONTEXT 選項替代呼叫 WinHttpSetOption。 在此情況下,應用程式會在 WinHttpSetOption 的 lpBuffer 參數中指定WINHTTP_NO_CLIENT_CERT_CONTEXT宏。 如需詳細資訊,請參閱 WINHTTP_OPTION_CLIENT_CERT_CONTEXT 選項。Windows Server 2003 SP1、Windows XP SP2 和 Windows 2000: 不支援此錯誤。 |
|
與伺服器的連線已重設或終止,或遇到不相容的 SSL 通訊協定。 例如,除非客戶端特別啟用 SSL2,否則 WinHTTP 5.1 版不支援 SSL2。 |
|
無法執行要求的作業,因為提供的句柄未處於正確的狀態。 |
|
針對此作業提供的句柄類型不正確。 |
|
發生內部錯誤。 |
|
URL 無效。 |
|
登入嘗試失敗。 發生此錯誤時,應該使用 WinHttpCloseHandle 關閉要求句柄。 必須先建立新的要求句柄,再重試原本產生此錯誤的函式。 |
|
無法解析伺服器名稱。 |
|
作業已取消,通常是因為要求在作業完成之前關閉的句柄。 |
|
當傳入回應超過內部 WinHTTP 大小限制時傳回。 |
|
在伺服器所傳送的安全套接字層 (SSL) 憑證中找到一或多個錯誤。 若要判斷發生何種類型的錯誤,請透過狀態回呼函式中的 WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 通知進行驗證。 如需詳細資訊,請參閱 WINHTTP_STATUS_CALLBACK。 |
|
WinHTTP 函式支援已關閉或卸除。 |
|
要求逾時。 |
|
URL 指定了 “HTTP:” 或 “https:” 以外的配置。 |
|
記憶體不足,無法完成要求的作業。 (Windows 錯誤碼) Windows Server 2003、Windows XP 和 Windows 2000: 使用 [WINHTTP_OPTION_PORT_RESERVATION ] 選項設定的 TCP 保留範圍不夠大,無法傳送此要求。 |
|
dwTotalLength 參數中指定的內容長度不符合 Content-Length 標頭中指定的長度。
lpOptional 參數必須是 NULL,而且當 Transfer-Encoding 標頭存在時,dwOptionalLength 參數必須是零。 當 Transfer-Encoding 標頭存在時,便無法顯示 Content-Length 標頭。 |
|
應用程式必須因重新導向或驗證挑戰而呼叫 WinHttpSendRequest 。
Windows Server 2003 SP1、Windows XP SP2 和 Windows 2000: 不支援此錯誤。 |
備註
即使 WinHTTP 用於異步模式,也就是說,在 WinHttpOpen 中設定WINHTTP_FLAG_ASYNC時,此函式仍可同步或異步操作。 不論是哪一種情況,如果成功傳送要求,則會呼叫應用程式,並將完成狀態設定為 WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE。 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR完成表示作業以異步方式完成,但失敗。 收到 WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 狀態回呼後,應用程式就可以開始使用 WinHttpReceiveResponse 從伺服器接收回應。 之前,無法呼叫其他異步函式,否則 會傳回ERROR_WINHTTP_INCORRECT_HANDLE_STATE 。
應用程式不得刪除或改變 lpOptional 指向的緩衝區,直到要求句柄關閉或 WinHttpReceiveResponse 的呼叫完成為止,因為收到回應時可能會遇到需要選擇性數據的驗證挑戰或重新導向。 如果作業必須使用 WinHttpCloseHandle 中止,則應用程式必須讓緩衝區保持有效狀態,直到收到回呼 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 並出現 ERROR_WINHTTP_OPERATION_CANCELLED 錯誤碼為止。
如果以同步方式使用 WinHTTP,也就是說,在 WinHttpOpen 中未設定WINHTP_FLAG_ASYNC時,即使註冊回呼函式,也不會呼叫具有完成狀態的應用程式。 在此模式中,當 WinHttpSendRequest 傳回時,應用程式可以呼叫 WinHttpReceiveResponse。
WinHttpSendRequest 函式會將指定的要求傳送至 HTTP 伺服器,並允許用戶端指定其他標頭以連同要求一起傳送。
此函式也可讓用戶端指定選擇性數據,以緊接在要求標頭之後傳送至 HTTP 伺服器。 這項功能通常用於寫入作業,例如 PUT 和 POST。
應用程式可以在對 WinHttpSendRequest 的多個呼叫中使用相同的 HTTP 要求句柄來重新傳送相同的要求,但應用程式必須讀取先前呼叫傳回的所有數據,才能再次呼叫此函式。
會驗證以這個函式新增的要求標頭名稱和值。 標頭的格式必須正確。 如需有關有效 HTTP 標頭的詳細資訊,請參閱 RFC 2616。 如果使用無效的標頭,此函式會失敗, 而且 GetLastError 會傳回 ERROR_INVALID_PARAMETER。 未新增無效的標頭。
Windows 2000: 從多個線程傳送要求時,網路和CPU效能可能會大幅降低。
Windows XP 和 Windows 2000: 請參閱 運行時間需求。
WinHttpSetStatusCallback
如果狀態回呼函式已經與 WinHttpSetStatusCallback 一起安裝,則下列在 WinHttpSetStatusCallback參數中設定的下列通知會指出傳送要求的進度:- 未實作WINHTTP_CALLBACK_STATUS_DETECTING_PROXY ()
- 只在異步模式中WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE ()
- WINHTTP_CALLBACK_STATUS_REDIRECT
- WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
- WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
- WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
- WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
- WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
- WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
- WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
- WINHTTP_CALLBACK_STATUS_REQUEST_SENT
- WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
- WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
- WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
- WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
支援大於 4 GB 上傳
從 Windows Vista 和 Windows Server 2008 開始,WinHttp 支援使用 Content-Length 標頭,將檔案的大小上傳至LARGE_INTEGER (2^64 位元組) 。 呼叫 WinHttpSendRequest 中指定的承載長度限制為 DWORD (2^32 個字節的大小) 。 若要將數據上傳至大於 DWORD 的 URL,應用程式必須在要求的 Content-Length 標頭中提供長度。 在此情況下,WinHttp 用戶端應用程式會呼叫 WinHttpSendRequest ,並將 dwTotalLength 參數設定為 WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH。如果 Content-Length 標頭指定長度小於 2^32,應用程式也必須在 WinHttpSendRequest 呼叫中指定內容長度。 如果 dwTotalLength 參數不符合 Content-Length 標頭中指定的長度,則呼叫會失敗並傳回 ERROR_INVALID_PARAMETER。
Content-Length 標頭可以在 WinHttpAddRequestHeaders 的呼叫中新增,也可以在 WinHttpSendRequest 的 lpszHeader 參數中指定,如下列程式代碼範例所示。
BOOL fRet = WinHttpSendRequest(
hReq,
L"Content-Length: 68719476735\r\n",
-1L,
WINHTTP_NO_REQUEST_DATA,
0,
WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
pMyContent);
傳輸編碼標頭
從 Windows Vista 和 Windows Server 2008 開始,WinHttp 可讓應用程式對傳送至伺服器的數據執行區塊傳輸編碼。 當 winHttp 要求上存在 Transfer-Encoding 標頭時,WinHttpSendRequest 呼叫中的 dwTotalLength 參數會設定為 WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,而應用程式會在一或多個對 WinHttpWriteData 的呼叫中傳送實體主體。 WinHttpSendRequest 的 lpOptional 參數必須是 NULL,而 dwOptionLength 參數必須是零,否則會傳回ERROR_WINHTTP_INVALID_PARAMETER錯誤。 若要終止區塊式數據傳輸,應用程式會產生零長度區塊,並在最後一次呼叫 WinHttpWriteData 時傳送它。範例
下列程式代碼範例示範如何取得 HINTERNET 句柄、開啟 HTTP 工作階段、建立要求標頭,並將該標頭傳送至伺服器。
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP Request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"PUT",
L"/writetst.txt",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a Request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
0, 0);
// Place additional code here.
// Report errors.
if (!bResults)
printf("Error %d has occurred.\n",GetLastError());
// Close open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows XP、Windows 2000 Professional 與 SP3 [僅限傳統型應用程式] |
最低支援的伺服器 | Windows Server 2003、Windows 2000 Server 與 SP3 [僅限桌面應用程式] |
目標平台 | Windows |
標頭 | winhttp.h |
程式庫 | Winhttp.lib |
Dll | Winhttp.dll |
可轉散發套件 | Windows XP 和 Windows 2000 上的 WinHTTP 5.0 和 Internet Explorer 5.01 或更新版本。 |
另請參閱
關於 Microsoft Windows HTTP Services (WinHTTP)
WINHTTP_STATUS_CALLBACK