如何使用 Windows.Web.Http 連線到 HTTP 伺服器 (HTML)

[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]

使用 Windows.Web.Http 命名空間中的 Windows.Web.Http.HttpClient 類別,將 GET 要求傳送到 Web 服務並抓取回應。

[立即取得 HTTPClient 範例。]

Windows.Web.Http 命名空間中的類別為現代化 HTTP 用戶端應用程式提供程式設計介面。Windows.Web.Http 命名空間和相關的 Windows.Web.Http.HeadersWindows.Web.Http.Filters 命名空間提供 HTTP 用戶端元件,這些元件讓使用者能夠透過 HTTP 提出 HTTP 要求,以及接收來自現代化 Web 服務的 HTTP 回應。

Windows 8.1 導入了 Windows.Web.Http,這是在連線到 HTTP 和表象化狀態轉換 (REST) Web 服務的 Windows 應用程式中使用的 Windows 執行階段命名空間。 這個新的 API 可以在所有支援的語言上提供完整功能的支援,並取代原本針對 Windows 8 發佈的 HTTP API。

這個新的 API 取代了先前在 Windows 8 中每個語言投影都會用到的三個不同功能的 API。

對於基本的要求操作,新的 API 提供簡單的介面來處理最常見的工作,並提供合理的預設值,用來進行可套用到大多數案例的驗證 (AUTH)。如果是更複雜的 HTTP 操作,即會包含其他功能。

  • 適用於常見動詞 (DELETEGETPUTPOST) 的方法

  • 常見驗證設定與模式的支援

  • 存取傳輸相關的安全通訊端層 (SSL) 詳細資料

  • 在進階應用程式中包含自訂篩選

  • 取得、設定及刪除 Cookie

  • 非同步方法中的 HTTP 要求進度資訊

Windows.Web.Http.HttpClient 類別是用於透過 HTTP 傳送和接收基本要求。它提供主要類別,用來從 URI 識別的資源傳送 HTTP 要求以及接收 HTTP 回應。這個類別可以用來將 GET、PUT、POST、DELETE 以及其他要求傳送到 Web 服務。每一個要求在傳送時,會以非同步作業的方式進行。

Windows.Web.Http.HttpRequestMessage 類別代表 Windows.Web.Http.HttpClient 所傳送的 HTTP 要求訊息。Windows.Web.Http.HttpResponseMessage 類別代表從 HTTP 要求收到的 HTTP 回應訊息。HTTP 訊息是由 IETF 定義在 RFC 2616 中。

Windows.Web.Http 命名空間提供一些不同的類別,代表與 HTTP 要求或 HTTP 回應相關聯的 HTTP 內容 (HTTP 實體內容和內容標題,包含 Cookie)。 這些不同的類別讓內容能夠使用緩衝區、字串、串流,以及使用 application/x-www-form-urlencoded MIME 類型、multipart/* MIME 類型及 multipart/form-data MIME 類型編碼的名稱/值資料。 此外,還能定義自訂內容。

在這個範例中,會使用 HttpStringContent 類別,以字串形式代表 HTTP 回應。

Windows.Web.Http.Headers 命名空間支援建立 HTTP 標頭與 Cookie,接著將它們當成屬性來與 HttpRequestMessageHttpResponseMessage 物件產生關聯。

先決條件

這個主題的下列範例是使用 JavaScript 和 HTML 撰寫的。您必須對 RFC 2616 中詳述的 HTTP 要求有基本的了解。

同時還能夠在使用 JavaScript 和 HTML 的應用程式中利用 WinJS.xhrXMLHttpRequest 提出 HTTP 要求。如需詳細資訊,請參閱連線到 Web 服務 (使用 JavaScript 的 Windows 執行階段應用程式)

指示

步驟 1: 建立新專案

  1. 開啟 Microsoft Visual Studio 2013,然後選取 [檔案] 功能表的 [新增專案]****。
  2. 在範本清單中,選擇 [JavaScript]。
  3. 在該區段下,選擇 [Store apps]。
  4. 在該區段下,選取 [Universal Apps]、[Windows apps] 或 [Windows Phone apps] (取決於您的目標平台),然後選取 [空白的應用程式]。
  5. 將應用程式命名為 HttpClientGet,然後按一下 [確定]****。

步驟 2: 設定功能以啟用網路存取

您需要為應用程式設定網路功能,才能啟用私人家用網路、公司網路以及網際網路的存取。因為用戶端連線到 Web 服務,所以您需要為這個應用程式啟用網路功能。

對於使用 Windows.Web.Http.HttpClient 連線到不同電腦上 Web 服務的應用程式,需要設定應用程式的網路功能。如果應用程式需要以用戶端的形式連線到網際網路上的 Web 服務,則需要 [網際網路 (用戶端)] 功能。如果應用程式需要以用戶端的形式連線到家用或工作網路上的 Web 服務,則需要 [私人網路 (用戶端與伺服器)]**** 功能。

注意  在 Windows Phone,只有一個網路功能 ([網際網路 (用戶端與伺服器)]) 能啟用應用程式的所有網路存取功能。

 

如果 Web 服務與應用程式在同一部電腦上執行,就需要回送存取。利用 Visual Studio 2013 開發和執行的應用程式會自動登錄,不受回送限制的約束。如需詳細資訊,請參閱如何啟用回送和偵錯網路隔離

如需網路存取的詳細資訊,請參閱如何設定網路功能

如果應用程式會存取網際網路、私人網路或公司網路上的 Web 服務,則在部署之前需要使用這些步驟來設定網路功能。

  1. 使用 Visual Studio 2013 開啟 package.appxmanifest 檔案。

  2. 選取 [功能]**** 索引標籤。

  3. 若要建置 Windows 版的範例,請選取 [網際網路 (用戶端)] 和 [私人網路 (用戶端和伺服器)]**** 功能。

    若要建置 Windows Phone 版的範例,請選取 [網際網路 (用戶端與伺服器)] 功能。

  4. 儲存並關閉資訊清單檔案。

步驟 3: 新增 HTML UI

  • 在本節中,我們會以 HTML 來定義應用程式配置,以指定應用程式中每個物件的概略大小和位置。 我們透過新增用來顯示資料的控制項和內容,以完成應用程式的 UI。

    這個範例使用簡單的 HTML UI 元素,其中包括下列各項:

    • 含有 class (用於文字標籤和輸入 URI 位址的輸入欄位) 以及 button (用於啟動非同步要求) 的控制項。

    • 含有 class 的控制項,其中包含可顯示目前狀態的文字標籤和文字欄位。這是將顯示狀態和錯誤訊息的位置。這個控制項也包含 class,從 Web 服務接收的輸出會顯示在此處。本範例中,HTTP GET 作業的結果會顯示成包含 HTML 標記的純文字。

    開啟 [js] 資料夾並開啟現有的 default.js 檔案,然後將下列 UI 元素新增到這個檔案中。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>HttpClientGet</title>
    
        <!-- WinJS references - Windows -->
        <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
    
        <!-- WinJS references - Phone -->
        <link href="/css/ui-themed.css" rel="stylesheet" />
        <script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
        <script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>
    
        <!-- HttpClientGet references -->
        <link href="/css/default.css" rel="stylesheet" />
        <script src="/js/default.js"></script>
        <script src="/js/mainpage.js"></script>
    </head>
    
    <body>
        <div data-win-control="SampleInput">
            <p> Download the contents of a page and display it. </p>
            <p class="clear">
                <label for="inputAddress">URI Address:</label>
                <input type="text" id="inputAddress" value="https://www.contoso.com" />
            </p>
            <p>
                <button id="startButton">Start</button>
            </p>
        </div>
        <div data-win-control="SampleOutput">
            <p class="clear">
                <label for="statusText">Status:</label>
                <input type="text" id="statusText" value="" />
            </p>
            <textarea id="outputView"></textarea>
        </div>
    </body>
    </html>
    

步驟 4: 建立 HttpClient

  • 首先建立 Windows.Web.Http.HttpClient 物件並新增 user-agent 標頭。

    HttpClient 物件預設是不會將任何 user-agent 標頭與 HTTP 要求一起傳送。某些 HTTP 伺服器 (包含一些 Microsoft 網頁伺服器) 要求從用戶端傳送的 HTTP 要求中需包含 user-agent 標頭。如果沒有任何標頭,HTTP 伺服器會傳回錯誤。我們需要使用 Windows.Web.Http.Headers 命名空間中的類別來新增 user-agent 標頭。我們將這個標頭新增到 HttpClient.DefaultRequestHeaders 屬性,以避免發生這些錯誤。

    開啟 [js] 資料夾並新增 mainpage.js 檔案,然後將下列程式碼新增到檔案中。

    (function () {
        "use strict";
    
        var httpClient;
        var httpPromise;
    
        var page = WinJS.UI.Pages.define("/html/mainpage.html", {
            ready: function (element, options) {
                document.getElementById("startButton").addEventListener("click", start, false);
    
                httpClient = new Windows.Web.Http.HttpClient();
    
                // Add a user-agent header
                headers = httpClient.defaultRequestHeaders;
    
                // UserAgent is a HttpProductInfoHeaderValueCollection
                // A collection of HttpProductInfoHeaderValue items
    
                // The safe way to check a header value from the user is the TryParseAdd method
                // Since we know this header is okay, we use ParseAdd with will throw an exception
                // with a bad value 
    
                headers.userAgent.parseAdd("ie");
                headers.userAgent.parseAdd("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
            }
        });
    })();
    

    開啟 [js]**** 資料夾和 default.js 檔案,然後將下列程式碼新增到檔案中。

    (// For an introduction to the Blank template, see the following documentation:
    // https://go.microsoft.com/fwlink/p/?LinkID=232509
    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    startButton.onclick = start;
    
                } else {
                    startButton.onclick = start;
                }
                args.setPromise(WinJS.UI.processAll());
            }
        };
    
        app.oncheckpoint = function (args) {
            // This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
        app.start();
    })();
    

步驟 5: 傳送 GET 要求並接收回應

  • 按一下 [開始] 按鈕後,我們會先驗證 [inputAddress]**** 中指定的 URI 是否有效。接著,使用該 URI 傳送 GET 要求,並等候接收來自 HTTP 伺服器的回應。

    多數工作是在開始 Button 的 click 處理常式中完成。按一下此按鈕時,即會更新 statusTextoutputView UI 元素中的文字。系統會先檢查輸入 URI 位址,以確定使用者傳送的是有效的 URI 位址。如果使用者傳送的是有效的 URI,應用程式接著會將 HTTP GET 要求傳送到指定的 URI,並等候 HTTP 回應。如果發生錯誤或例外狀況,會在 statusText UI 元素中顯示結果。如果沒有發生錯誤,來自 Web 服務的回應會顯示在 outputView UI 元素中。

    如果傳送到 Windows.Foundation.Uri 物件建構函式的統一資源識別元 (URI) 字串無效時,即會擲回例外狀況。

    在 JavaScript 中,並未提供任何方法來嘗試和剖析 URI 的字串。若要在這個情況下擷取此例外狀況,可在建構 URI 的程式碼前後使用 try/catch 區塊。

    此範例也會檢查 URI 中的 HTTP 配置為 HTTP 或 HTTPS,因為這些是 Windows.Web.Http.HttpClient 唯一支援的配置。

    在 JavaScript 中使用 thendone 關鍵字,非同步傳送 GET 要求以及抓取回應時所使用的程式碼,與我們同步完成此作業時所使用的程式碼類似。

    網路錯誤 (例如,連線中斷、連線失敗、HTTP 伺服器故障) 的例外狀況可能隨時發生。這些錯誤會造成擲出例外狀況。如果您的應用程式不處理例外狀況,它可能會造成您整個應用程式被執行階段終止。 您必須編寫程式碼,在呼叫大多數非同步網路方法時處理例外狀況。有時候,在例外狀況發生時,會重試網路方法,試圖解決問題。其他時候,您的應用程式需要規劃,在沒有網路連線的情況下,使用之前快取的資料繼續工作。如需處理網路例外狀況的詳細資訊,請參閱處理網路應用程式中的例外狀況

    如果 Web 伺服器傳回的 HTTP 錯誤狀態碼 HttpResponse.StatusCode 不在要求的 Successful 範圍 (200-299) 內,HttpResponse.EnsureSuccessStatusCode 方法即會擲回例外狀況。如果發生錯誤,我們會針對任何例外狀況使用 try/catch 區塊,然後列印出 statusText UI 元素中的例外狀況訊息。

    HttpResponse.Content 屬性代表 HTTP 回應的內容。HttpClient.GetAsync(Uri) 方法會以非同步作業的方式,以字串形式讀取 HTTP 內容。 為了更清楚的顯示,我們以新行取代傳回之 HTML 文字中的 <br> 標記。如果這個方法成功,即會在 statusText UI 元素中顯示 HttpResponse.StatusCode,以及在 outputView UI 元素中顯示 Web 服務所傳回的 HttpResponse.Content

    開啟 [js] 資料夾,然後將下列程式碼新增到 mainpage.js 檔案中。

        function start()
        {
    
            var response = new Windows.Web.Http.HttpResponseMessage();
    
            var statusText = document.getElementById("statusText");
            var outputView = document.getElementById("outputView");
    
            // The value of 'inputAddress' is set by the user 
            // and is therefore untrusted input. 
            // If we can't create a valid absolute URI, 
            // We notify the user about the incorrect input.
    
            statusText.Text = "Testing URI is valid.";
    
            var uriString = document.getElementById("inputAddress").value.trim();
            if (!uriString) {
                return;
            }
    
            var resourceUri;
            try {
               resourceUri = new Windows.Foundation.Uri(uriString);
            }
            catch (Exception) {
                statusText.Text = "Invalid URI, please re-enter a valid URI.";
                return;
            }
    
            if (resourceUri.schemeName != "http" && resourceUri.schemeName != "https") {
                statusText.Text = "Only 'http' and 'https' schemes supported. Please re-enter URI";
                return;
            }
    
            var responseBodyAsText="";
            outputView.Text = "";
            statusText.Text = "Waiting for response ...";
    
            httpPromise = httpClient.getAsync(resourceUri).then(function (response) {
                outputStatus = response.statusCode + " " + response.reasonPhrase;
    
                response.EnsureSuccessStatusCode();
    
                response.content.readAsStringAsync().then(function (responseBodyAsText) {
                // Format the HTTP response to display better
                responseBodyAsText = responseBodyAsText.replace(/<br>/g, "\r\n");
                outputView.value = responseBodyAsText;
                return response;
            });
        )};
    
        httpPromise.done(function (response) {
            statusText.value = response.StatusCode + " " + response.ReasonPhrase + "\r\n";
        }, onError);
    
        function onError(error) {
            statusText.value = "Error = " + error.number + "  Message: " + error.message;
        }
    
    })();
    

    Windows.Web.Http.HttpClient 使用 WinInet 傳送 HTTP 和 Web 服務要求以及接收回應。WinInet 針對 HTTP 連線操作所使用的預設逾時值為 60 秒。如果 HTTP 伺服器或 Web 服務暫時當機或被防火牆封鎖,且伺服器沒有或無法回應 Windows.Web.Http.HttpClient 要求,WinInet 會先等候預設的 60 秒,然後才會傳回導致在應用程式中擲回例外狀況的錯誤。如果 HTTP 伺服器名稱的名稱查詢針對該名稱傳回多個 IP 位址,WinInet 會先嘗試數個該網站的其他 IP 位址 (每個都使用預設的 60 秒逾時),然後才會失敗。提出 HTTP 或 Web 服務要求的應用程式會先等候數分鐘重試多個 IP 位址,然後 WinInet 才會傳回錯誤並擲回例外狀況。當應用程式停止運作時,使用者即會看見此行為。建立連線之後,WinInet 針對傳送和接收操作所使用的預設逾時為 30 秒。

    若要讓應用程式更具回應性並將這些問題減至最低,應用程式可藉由在 Windows.Web.Http.HttpClient 操作上設定較短的逾時來增強,讓操作儘速在該逾時 (而非預設的 WinInet 設定) 之後失敗。如需如何設定逾時的詳細資訊,請參閱使用 WinJS.xhr 或 HttpClient 設定逾時值如何在通訊端作業上設定逾時

備註

在這個主題中,我們檢閱如何使用 Windows.Web.Http.HttpClient 類別,將 GET 要求傳送到 Web 服務,並使用 Windows.Web.Http.HttpResponseMessageWindows.Web.Http.Headers 命名空間中的相關類別來抓取回應。

相關主題

其他資源

連線到 Web 服務

處理網路應用程式中的例外狀況

如何設定網路功能

如何啟用回送以及偵錯網路隔離

使用 WinJS.xhr 或 HttpClient 設定逾時值

參考

Windows.Foundation.Uri

Windows.Web.Http

Windows.Web.Http.Filters

Windows.Web.Http.Headers

範例

HttpClient 範例

Web 驗證範例