本文章是由機器翻譯。

安全性

使用 Windows 運行時和 OAuth 訪問聯機服務

Tim Kulp

下載代碼示例

回顧從前的 Web 1.0 時代,網站只是供人閱讀的內容的存儲庫,僅此而已。 當 Web 2.0 迅速應用於開發領域時,網站變成了聯機服務,並配備了各種 API,供開發人員用來組合和匹配元件、資料和功能。 現在,開發人員可以通過混合 Web 應用程式來訪問豐富的內容庫,而避免了在其伺服器機房中存儲資料的開銷。

借助于 Windows 運行時 (WinRT),您可以將混合 Web 應用程式的強大功能融入到您的下一個 Windows 應用商店應用程式中。 不論您是使用 XmlHttpRequest (XHR) 管理資料,還是使用 WebAuthenticationBroker 類向遠端服務進行身份驗證,Windows JavaScript 庫 (WinJS) 和 Windows 運行時都使您能夠輕鬆地將聯機服務與應用程式相混合。

Contoso 照片完成

在本文中,我打算構建一個名為 Contoso Photo Finish 的混合 Web 應用程式。 通過該應用程式,跑步者可以跟蹤其里程併發布其跑步的圖片。 許多跑步者喜歡在社交網路上分享其跑步的距離和位置等此類資訊。 通過 Contoso Photo Finish,使用者可以告訴朋友關於其跑步的資訊並在 Facebook 上發佈評論和圖片。 此應用程式將連接到兩個不同的服務:

  • 連接到 Windows SkyDrive 以檢索關於跑步的圖片
  • 連接到 Facebook 向朋友發佈圖片供其查看

Contoso Photo Finish 將結合這兩項服務來為使用者提供連接體驗。 本文假定您已打開 Visual Studio 2012 並且 JavaScript | Windows 應用商店 | 空白應用程式範本已準備就緒,您可以開始編寫代碼了。

混合 Web 應用程式面臨的障礙:授權和身份驗證

如果應用程式(Web 或 Windows 應用商店)要向 Facebook 發佈內容,第一個要克服的障礙是身份驗證。 Facebook 需要知道是誰正在連接到它。 當使用者嘗試登錄應用程式時,他們會聲明一個身份(通常以使用者名形式)和一個憑據(如密碼、安全權杖、生物特徵設備等),以證明自己對所請求的身份應具有存取權限。 身份驗證是通過憑據驗證使用者身份的過程。

在對使用者進行身份驗證後,混合 Web 應用程式將面臨另一個挑戰:確定使用者可以在系統中執行什麼操作。 授權是根據某種屬性或安全形色成員資格,允許或拒絕某個身份嘗試執行操作的過程。 例如,在 Twitter 中,我的身份就無權刪除所有使用者的所有 tweet。 我無權執行該操作,因為我不是有權執行此操作的安全形色的成員。 身份驗證和授權 (A&A) 兩者共同提出了這樣一個問題:使用者、使用者身份以及使用者可以執行什麼操作?

混合 Web 應用程式使這些問題變得更麻煩,因為構建混合 Web 應用程式的開發人員對於存儲身份、憑據和安全形色的位置(也稱為憑據存儲)不具備存取權限。 因此,如果我無法驗證使用者的身份以及使用者可以執行什麼操作,我怎麼才能為諸如 Facebook 的應用程式構建混合 Web 應用程式呢? OAuth 應運而生!

OAuth:訪問資源,而非應用程式

OAuth 可以解決混合 Web 應用程式面臨的 A&A 挑戰。 不妨想像一下,應用程式 X 要訪問聯機服務 Y 中的內容。 此時使用者不是針對應用程式 X 進行身份驗證,而是針對聯機服務 Y 進行身份驗證,因為使用者的憑據存儲在聯機服務 Y 的憑據存儲中。 然後,使用者允許應用程式 X 在有限的時間內訪問聯機服務 Y 中的指定內容。 訪問聯機服務 Y 資源的許可權將作為訪問權杖(有時就稱為「權杖」)返回給應用程式 X。

在傳統的 Web A&A 模型中,兩個參與者共同確定使用者的存取權限:應用程式和使用者(或伺服器和用戶端)。 在 OAuth 中,引入了第三個參與者:資源伺服器。 資源伺服器是將資源(如照片)存儲在用戶端需要訪問的伺服器上的協力廠商。 在 Contoso Photo Finish 中,Facebook 是資源伺服器。 Contoso Photo Finish 要訪問的資源是使用者的狀態,以便發佈消息。

OAuth 用戶端及其身份驗證過程

OAuth 中有兩種類型的用戶端,要使用哪種類型由用戶端的信任層級決定。 機密用戶端可以確保其憑據安全,這是高度信任的環境所應該提供的。 提供以下服務的伺服器端 Web 應用程式就是機密用戶端的一個示例:其中,用戶端金鑰能夠在可控制的安全環境中得到維護。 機密用戶端使用授權代碼過程來獲取安全權杖,其方法是向資源伺服器提供用戶端金鑰以作為對用戶端進行身份驗證的手段。

公共用戶端無法確保其憑據的安全性,因為它們在不友好的環境中運行。 使用者代理應用程式(也即 JavaScript Web 應用程式)或本機應用程式(如 Windows 應用商店應用程式)就是公共用戶端的示例。 公共用戶端使用「隱式授予」過程來獲取安全權杖,因為在開發人員無法控制的惡意環境中,無法以安全方式存儲用戶端金鑰。

Windows 應用商店應用程式可以配置為對 OAuth 使用隱式授予或授權代碼過程(您可以通過 bit.ly/yQjyQZ 閱讀有關隱式授予和授權代碼過程的詳細資訊)。 只要應用程式不受開發人員控制,就使用隱式授予,這是安全性的最佳實踐。

圖 1 中,我考察了隱式授予過程,其中用戶端通過嘗試向資源伺服器確定使用者身份來啟動會話。

Windows Store App Implicit Grant Conversation
圖 1 Windows 應用商店應用程式隱式授予會話

圖 1 中所示的步驟解釋如下:

  1. Windows 應用商店應用程式需要執行某種功能,而該功能要求對 Facebook API 具有存取權限。
  2. 使用者通過一個 URI 連接到資源伺服器,而該 URI 中包括有關試圖訪問 Facebook API 的 Windows 應用商店應用程式的資訊。 這通常採用應用程式 ID 或用戶端 ID 代碼的形式。 使用者提供使用者名和密碼以登錄到 Facebook。
  3. 假設登錄成功,此時 Facebook 向 Windows 應用商店應用程式提供一個訪問權杖。
  4. Windows 應用商店應用程式現在可以使用由 Facebook 提供的訪問權杖來獲取使用者的源、發佈圖片等等,從而向使用者提供 Facebook API 中的資料。

通過新的 Windows.Security.Authentication.Web 命名空間,讓這一會話發生將變得極其簡單。

WebAuthenticationBroker

在 Windows 應用商店應用程式中,WebAuthenticationBroker 類 (bit.ly/RW8czT) 是這樣一個元件:它將與資源伺服器通信、提供登錄控制並回應成功登錄,所有這些都不需要 Windows 應用商店應用程式知道有關使用者憑據的任何資訊。 應用程式範例 Contoso Photo Finish 需要將圖片發佈到 Facebook。 這要求使用者針對 Facebook 進行身份驗證並收到一個訪問權杖。

向名為 input.html 的 Contoso Photo Finish 專案添加一個新的頁面控制項。 預設情況下,Visual Studio 提供了許多標記。 將主要內容部分中的「<p>Content goes here.</p>」替換為以下按鈕:

<input type="button" id="btnAddRun" value="Add Run" />

這是使用者將按一下以便向 Photo Finish 添加跑步的按鈕。 現在打開 input.js 並添加以下函數:

function btnAddRun_Click(e) {
  var facebookOauthUrl = "https://www.facebook.com/dialog/oauth";
  var facebookClientId = "[YOUR CLIENT ID]";
  var redirectUrl = "https://www.facebook.com/connect/login_success.html";
  var requestUri = Windows.Foundation.Uri(facebookOauthUrl +
    "?client_id=" + facebookClientId +
    "&redirect_uri=" + encodeURIComponent(redirectUrl) +
    "&response_type=" +
    "token&scope=read_stream,publish_actions&display=popup");
  var callbackUri = Windows.Foundation.Uri(redirectUrl);
  // Web authentication broker will go here
}

此代碼會建立要在身份驗證請求中使用的變數。 第一個變數是 Facebook OAuth 服務的 URL。 用戶端 ID 是一個應用程式識別碼,Facebook 使用此識別碼將 Contoso Photo Finish 標識為 Facebook API 將與其交互的應用程式。 此類識別碼通常是在應用程式向資源伺服器註冊時分配給該應用程式的。 某些資源伺服器將這些識別碼稱為用戶端 ID、應用程式 ID 或僅僅稱為 ID。 在資源伺服器的 API 文檔中可以找到要使用哪個 ID。

redirectUrl 參數確定當使用者進行身份驗證並批准應用程式訪問指定的資源後,應用程式將前往何處。 在這種情況下,redirectUrl 設置為可用於所有 Facebook API 應用程式的 Facebook 標準位置。 一些服務要求在註冊 Windows 應用商店應用程式時,應向資源伺服器標識此應用程式的 URI。 可以使用 Web 身份驗證代理程式的 getCurrentApplicationCallbackUri 方法找到應用程式的 URI。 這將返回應用程式的本地上下文 URI(以「ms-app://」開頭)。 某些資源伺服器不支援將 ms-app:// 作為 redirectUrl 的有效協定,在這種情況下,您應檢查預設的重定向位址,如 Facebook 提供的此類重定向位址。

接下來,定義 callbackUri。 這是向 Web 身份驗證代理程式通知何時完成身份驗證並將控制權返還給 Windows 應用商店應用程式的位址。 代理程式從不實際轉至此 URL;它只是監視資源伺服器是否調用此頁面,然後返回 callbackUri 以及附加的任何查詢字串或雜湊參數。 在這種情況下,雜湊參數「access_token」將向 Contoso Photo Finish 提供與此 API 交互所需的權杖。

WebAuthenticationBroker 類使用 authenticateAsync 方法連接到資源伺服器,並針對資源伺服器完成身份驗證過程。 當調用 authenticateAsync 時,應用程式將打開一個彈出式視窗,其中顯示資源伺服器的登錄螢幕,如圖 2 所示。 一旦完成了身份驗證或遇到了 callbackUri,快顯視窗將關閉。

Resource Server’s Login Pop-up from authenticateAsync
圖 2 調用 authenticateAsync 時顯示的資源伺服器的登錄快顯視窗

使用此快顯視窗的一個關鍵優勢在於:對於資源管理器,Windows 應用商店應用程式從不處理使用者的憑據,也不需要知道使用者的憑據。 應用程式只需知道資源伺服器返回的訪問權杖即可。 這種分隔措施使資源伺服器的憑據與應用程式相分離,這可避免通過應用程式存儲憑據所帶來的安全性風險。 除了安全性優勢之外,開發人員還不必對任何內容編碼即可獲得此介面;此介面內置於 authenticateAsync 方法中。 當開發人員調用此方法時,此方法將立即提供此介面。

現在,讓我們回過頭來說一說代碼。 用下列代碼替換「Web authentication broker will go here」注釋:

Windows.Security.Authentication.Web.WebAuthenticationBroker.
authenticateAsync(Windows.Security.Authentication.Web.
WebAuthenticationOptions.
none, requestUri, callbackUri)
.done(
  function (result) {
    // Check the response status here                 
  },
  function (ex) {
    Log(ex);
  }
);

authenticateAsync 方法採用三個參數(第三個是可選參數):

  1. WebAuthenticationOptions:此參數用於向 Web 身份驗證代理程式提供相關的說明,指示如何呈現身份驗證對話方塊或在回應中返回什麼資料。 在前面的示例中,應用程式使用「none」來說明一種常見的實施,也即使用預設設置,不向代理程式傳遞任何選項。
  2. requestUri:這是資源伺服器的登錄進入點。 在此情況下,Contoso Photo Finish 連接到 Facebook 的 OAuth 服務。 RequestUri 必須使用 HTTPS 協定通過安全連線相連。
  3. callbackUri:這是一個頁面,當導航到此頁面時,系統將控制權返還給 Windows 身份驗證代理程式,如前面所述。 此參數是可選的,但如果資源伺服器無法(或不想)重定向到 ms-app://,則此參數指示應用程式將以何種方式避開資源伺服器的控制。 例如,在前面的代碼中,當成功登錄後導航到 HTTPs://www.facebook.com/connect/login_success.html 時,Web 身份驗證代理程式將通過關閉身份驗證對話方塊並處理承諾的成功,從資源伺服器手中接管對應用程式的控制權。 CallbackUri 不必位於緊接的下一頁中;它可能位於嚮導之後,或位於資源伺服器網站上必然出現的某個其他過程之後。 此 URI 通常與 redirectUrl 相同,但它提供了靈活性,可根據需要延長身份驗證過程。

如果 Web 身份驗證代理程式連接到資源伺服器,則承諾獲得成功。 檢測身份驗證過程的結果是通過 WebAuthenticationResult 物件的 ResponseStatus 屬性來實現的。 在前面的代碼中,結果參數是 WebAuthenticationResult 物件以及三個屬性:回應資料(來自資源伺服器的資料)、ResponseErrorDetail(如果某項內容出錯,則錯誤詳情是什麼?)以及 ResponseStatus(身份驗證的狀態是什麼?)。 將「Check the response status here」注釋替換為圖 3 中所示的代碼。

圖 3 處理身份驗證過程的結果

switch (result.responseStatus) {
  case Windows.Security.Authentication.Web.WebAuthenticationStatus.success:
    var fragment = Windows.Foundation.Uri(result.responseData).fragment;
    if (fragment.indexOf("#access_token=") != -1) {
      var token = fragment.substring(
        new String("#access_token=").length,
        fragment.indexOf("&expires_in="));
      // Add API calls here
    }
    break;
  case Windows.Security.Authentication.Web.WebAuthenticationStatus.userCancel:
    Log(window.toStaticHTML(result.responseData));
    Display("User cancelled the authentication to Facebook.");
    break;
  case Windows.Security.Authentication.Web.WebAuthenticationStatus.errorHttp:
    Log(window.toStaticHTML(result.responseData));
    Display("An error occurred while communicating with Facebook.");
    break;
}

圖 3 所示的代碼中,每種狀態都進行了檢查,Log 方法記錄了來自資源伺服器的資訊,而 Display 方法告知使用者發生了什麼情況。 對於錯誤訊息,請記得顯示方便使用的消息以改進使用效果,並減少從系統生成的錯誤訊息中意外洩漏敏感資訊的可能性。 如果身份驗證獲得成功,系統將解析從 Facebook 返回的 URI 片段,並將其存儲在權杖變數中以用於 API 呼叫(有關實施詳情,請參閱「通過 XHR 獲取和發佈資訊」部分。

當 btnAddRun_Click 函數完成時,將其連接到 WinJS.UI.Pages.define { ready } 函數中的 btnAddRun 物件。

var btnAddRun = document.getElementById("btnAddRun");
if (null != btnAddRun)
  btnAddRun.addEventListener("click", btnAddRun_Click, false);

此時,應用程式具有一個訪問權杖,其中顯示使用者已通過資源伺服器的身份驗證。 在最後一部分中,應用程式將執行 API 命令以發送資料,但首先,應用程式需要將一些內容發送到 Facebook。

繪製圖畫

Windows 8 提供了各種允許應用程式彼此之間進行交流的合約,如搜索、共用和檔選取器。 通過這些合約,只需幾行代碼,就可以將任何應用程式轉換為混合 Web 應用程式。 Contoso Photo Finish 打算利用檔選取器合約的強大功能,以找出使用者跑步的圖像。

我喜歡 Windows Phone 的眾多原因之一是它與 SkyDrive 集成。 我可以立即將我的照片上載到雲中的存儲中,這樣,下一次我摔壞手機時(經常發生這種情況),就可以線上獲得我的圖片。 Windows 8 的 SkyDrive 應用程式向檔選取器提供資料,這使得從我的 SkyDrive 帳戶選擇檔與從圖片庫中選擇檔一樣簡單。 Contoso Photo Finish 混合 Web 應用程式的下一個部分將使用通過檔選取器從 SkyDrive 應用程式獲得的資料。 為此,input.html 也需要一些 . . 輸入內容。

使用圖 4 中所示的代碼替換現有的 btnAddRun 按鈕。 此代碼包括供使用者為 Contoso Photo Finish 提供內容的輸入欄位。 btnSelectPhoto 按鈕將使用檔選取器來選擇系統上要使用的檔。 向 input.js 添加一個新函數,此函數將是 btnSelectPhoto 的按一下處理常式:

function btnSelectPhoto_Click(e) {
  var imgSelectedPhoto = document.getElementById("imgSelectedPhoto");
  var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
  filePicker.fileTypeFilter.replaceAll([".jpg", ".jpeg", ".png"]);
  filePicker.suggestedStartLocation =
    Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
  filePicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
  // Pick file here
}

圖 4 為應用程式提供內容的輸入欄位

<p>
  <label>Distance</label>
  <input type="number" min="0" max="15" id="txtDistance"
    required /> miles
</p>
<p>
  <label>Comment</label>
  <input type="text" min="0" max="15" id="txtComment" />
</p>
<p>
  <label>Photo</label>
  <input id="btnSelectPhoto" value="Select Photo" type="button" />
  <img src="" id="imgSelectedPhoto" alt="Selected Photo" />
</p>
<p>
  <input type="button" id="btnAddRun" value="Add Run" />
</p>

此函數首先是設置 imgSelectedPhoto 變數,此變數將用於向使用者顯示所選照片。 接下來,該代碼創建一個檔選取器物件。 通過此檔選取器物件,Contoso Photo Finish 可以在系統上或在參與檔選取器合約的其他應用程式中,選擇要在此應用程式中打開並進行交互的檔或資料夾(此處只是檔)。 通過使用此檔案類型篩選器,代碼可限制檔選取器可以訪問哪些檔副檔名。 應用程式只能將圖像載入到 Facebook(按設計規定),因此,限制檔選取器只能處理指定的圖像檔案類型,可以避免使用者選擇具有不符合所需功能的無效副檔名的檔。 此外,由於應用程式的焦點是圖像,因此,檔選取器的起始位置設置為圖片庫。 這可以是各種預設位置(如音樂庫、文件庫、家庭組等),但當處理圖片時,起點理所當然是圖片庫。 檔選取器的最後一個設置是將 viewMode 設置為縮略圖。 此設置顯示檔的預覽,對於選擇圖像是理想的設置。

設置選項後,就該為跑步選擇要使用的檔了。 首先,在「use strict」語句的正下方添加以下兩個變數聲明:

var selectedPhotoStream = null;
var selectedPhotoFile = null;

在將資料載入到 Facebook 時,這些變數將為 btnAddRun_Click 函數容納檔值和流值。 現在,使用圖 5 中所示的代碼替代「Pick file here」注釋。

圖 5 選取檔

filePicker.pickSingleFileAsync().then(
  function (storageFile) {
    if (storageFile) {
      selectedPhotoFile = storageFile;
      selectedPhotoFile.openAsync(
        Windows.Storage.FileAccessMode.read).then(
        function (stream) {
          selectedPhotoStream = stream;
        document.getElementById("imgSelectedPhoto").src =
          URL.createObjectURL(selectedPhotoFile);
      },
      function (ex) {
        Log(ex);
        Display("An error has occurred while reading the file.");
      });   
     }
    else {
      Display("File was not selected");
    }
  });

圖 5 看起來是一些代碼,但歸根結底是三個操作:

  1. 選擇應用程式將通過檔選取器使用的檔 (pickSingleFileAsync)。
  2. 打開要讀取的檔流 (openAsync)。
  3. 將流和檔存儲到變數中供以後使用。

所有代碼對於處理檔和流都是標準的,但有一個例外:URL.createObjectURL 採用一個物件,並為該物件構建一個 URL,以便通過一個影像物件顯示此物件。 createObjectURL 方法處理許多物件類型,包括 Stream、StorageItem 和 MediaCapture。 通常,此方法用於顯示在 Windows 應用商店應用程式中顯示媒體內容(圖像、音訊或視頻)。 使用 createObjectURL 時要記住的一點是:當您完成使用 URL 時,確保通過 URL.revokeObjectURL 方法釋放它。 這可確保記憶體使用達到最佳狀態,並可防止 Windows 應用商店應用程式深陷於太多的臨時 URL 中。 有關 createObjectURL 的詳細資訊,請查看 bit.ly/XdhzOm 上的 MSDN 文檔。

最後,將 btnSelectPhoto_Click 事件與 btnSelectPhoto 物件相關聯。 在 WinJS.UI.Pages.define { ready } 函數中添加以下代碼:

var btnSelectPhoto = document.getElementById("btnSelectPhoto");
if (null != btnSelectPhoto)
  btnSelectPhoto.addEventListener(
    "click", btnSelectPhoto_Click, false);

此時,Contoso Photo Finish 有內容要發佈,而我具有針對 Facebook 進行身份驗證以進行發佈的機制。 現在,應用程式只需與 API 交互和連線引發內容。

通過 XHR 獲取和發佈資訊

您還記得 AJAX 是何時推陳出新並且變得如此令人激動的嗎? XHR 最初面世是在 Internet Explorer 5.5 中,它使 Web 開發人員開始重新考慮如何開發 Web 應用程式。 隨著時間推移,AJAX 也在不斷成長,許多不同的庫(如 jQuery)陸續納入一個易於理解且易於實施(這一點更重要)的解決方案中。 WinJS.xhr 延續了這一傳統,它通過一個簡單的 API 獲取資料並將資料發佈到聯機服務。

返回到 btnAddRun_Click 函數,並將「Add API calls here」注釋替換為圖 6 中所示的代碼。

圖 6 從 selectedPhotoStream 生成 Blob 物件

var fileBlob = MSApp.createBlobFromRandomAccessStream(
  selectedPhotoFile.contentType,
  selectedPhotoStream);
var message = "I just ran " + document.getElementById(
  "txtDistance").value + " miles with PhotoFinish! "
+ 
  document.getElementById("txtComment").value;
var data = new FormData();
data.append("source", fileBlob);
data.append("filename", selectedPhotoFile.
name);
data.append("access_token", token);
data.append("message", window.toStaticHTML(message));
WinJS.xhr({
  type: "POST",
  url: "https://graph.facebook.com/me/photos",
  data: data,
}).then(
  function (photoid_response) {
    ProcessResponse(photoid_response);
  },
  function (ex) {
    Display("An error occurred while posting the photo.");
    Log(ex);
  });

以前,應用程式將 StorageFile 和 Stream 存儲到 selectedPhotoFile 和 selectedPhotoStream 變數中。 MSApp.createBlobFromRandomAccessStream 採用 selectedPhotoStream 並生成一個 Blob 物件 (bit.ly/Stfu9z),應用程式隨後會將此物件作為 POST 參數傳遞到 Facebook。 這是一項很有用的功能,可將 WinRT 物件轉換為可通過 HTTP 傳輸的格式。

接下來,代碼使用 FormData 物件(HTML5 中新增的物件)創建將在 HTTP POST 中發送的參數。 FormData 是一個鍵/值對物件,只有一個方法:追加。 使用 append 方法,開發人員可以動態構建表單欄位,並使用 POST 提交這些欄位,就好像調用了表單的提交事件一樣。 FormData 也通過多部分/表單資料編碼來提供參數,就好像這些參數屬於某個表單一樣。 這樣,開發人員就可以向目標伺服器發佈任何輸入類型(包括檔)了。

注意,在 FormData.append 方法調用中,我使用 toStatic­HTML (bit.ly/ZRKBka),以確保消息內容是安全的以便進行傳遞。 如果使用 toStaticHTML,則將首先從消息變數中刪除任何事件屬性或腳本內容,然後才將該消息變數添加到 FormData 物件。 儘管我設想 Facebook 可很好地防止跨網站腳本攻擊(以及其他攻擊),但作為混合 Web 應用程式開發人員,我希望為夥伴應用程式提供乾淨的內容。 Internet 是個非常大的場所,因此我們都需要彼此密切注意雙方的應用程式。

代碼塊的剩餘部分是 WinJS.xhr 調用。 此時此刻,代碼使用 XHR 的一些更多屬性,包括:

  • type(類型):此屬性設置要使用的 HTTP 方法。 預設情況下,類型設置為 GET。 此代碼使用 POST,因為應用程式要向 Facebook API 發送內容。
  • data(資料):此屬性由要通過 POST 傳遞的參數組成。

當在 success 方法中返回承諾時,Contoso Photo Finish 處理照片 ID 供以後檢索。 如果發生錯誤,將顯示標準錯誤消息並記錄異常。

WinJS.xhr 與其他 XHR 包裝非常類似。 如果您熟悉 JavaScript 庫(如 jQuery),則可以輕鬆地選取 WinJS.xhr。 您可能遇到的一個問題是 WinJS.xhr 方法沒有超時選項,這一點與 XHR 不同。 設置超時是通過使用 WinJS.Promise.timeout 方法包裝 WinJS.xhr 調用來實現的 (bit.ly/Qgtx7a)。 通過在 WinJS.xhr 調用的開頭添加以下代碼,我將針對 POST 的超時設置為 10 秒:

WinJS.Promise.timeout(1000, WinJS.xhr({ ... });

如果 WinJS.xhr 承諾在 10 秒內未完成,承諾將超時,並通過超時承諾的錯誤函數來處理。

混合應用程式時的首要步驟

在本文中,我探討了通過 WinJS 和 Windows 運行時進行身份驗證、獲取檔和發送資料的內容。 我們以這些基本技能為基礎,可以設計出功能強大的 Windows 應用商店應用程式,而其功能僅受您的想像力和開發人員金鑰所限。 請參閱本文中的材料,並瞭解您喜愛的聯機服務。 使用 WinJS.xhr,您的 Windows 應用商店應用程式可以與連線提供的無數 API 進行交互。 借助于 Web 身份驗證代理程式,您的應用程式可以通過 OAuth 或 OpenID,將使用者與其連線個性、內容和社區相連接。 WinJS 和 Windows 運行時提供了各種工具,使您能夠輕鬆地構建在功能上超過其所有聯機服務總和的應用程式。

Tim Kulp 是位於美國巴爾的摩市的 FrontierMEDEX 公司開發小組的負責人。有關他的情況,請訪問 seccode.blogspot.com 上他的博客或訪問 Twitter (Twitter.com/seccode),在上面他談論了代碼、安全性以及巴爾的摩市的美食、風景。

衷心感謝以下技術專家對本文的審閱:蘇尼爾 Gottumukkala 和傑瑞米 · 種