使用 JavaScript 用戶端程式庫 (v2.0)

警告:本頁面說明 Google 的舊版 API (即 Google Data API);該 API 只與 Google Data API 目錄中列出的 API 相關,其中許多 API 已由新版 API 取代。如需特定新的 API 的相關資訊,請參閱新 API 的說明文件。如要瞭解如何使用新版 API 授權要求,請參閱 Google 帳戶驗證與授權

本文件說明如何使用 JavaScript 用戶端程式庫傳送 Google Data API 查詢,並解讀傳回的回應。

Google 提供一組支援多種程式設計語言的用戶端程式庫,可用於與擁有資料 API 的服務互動。透過這些程式庫,您可以建構 API 要求、將要求傳送至服務並接收回應。

本文件提供一些關於 JavaScript 用戶端程式庫的基本資訊,以及一組常見用途範例。

目標對象

本文件旨在協助 JavaScript 程式設計師撰寫用戶端應用程式,以便與 Google Data 服務互動。

本文假設您已瞭解 Google Data API 通訊協定背後的一般概念。同時假設您知道如何使用 JavaScript 編寫程式。

如需用戶端程式庫提供的類別和方法的參考資訊,請參閱 JavaScript 用戶端程式庫 API 參考資料 (JSdoc 格式)。

這份文件是按順序閱讀,每個範例都是以先前的範例為基礎。

使用條款

使用 JavaScript 用戶端程式庫時,您同意遵守《Google JavaScript 用戶端程式庫使用條款》。

資料模型與控管流程總覽

JavaScript 用戶端程式庫會使用一組類別來代表 Google Data API 使用的元素。

注意:資料的基礎表示法為 JSON,但用戶端程式庫提供抽象層,因此您無須直接使用 JSON 資料。如果您要在不使用用戶端程式庫的情況下直接使用 JSON,請參閱搭配 JSON 搭配 Google Data API 使用。

程式庫提供一種方法,可讓您以非同步方式將資料傳送至有資料 API 的服務,並從其接收資料。舉例來說,google.gdata.calendar.CalendarService.getEventsFeed() 方法會向 Google 日曆傳送資訊提供要求。您傳送的其中一個參數是接續函式 (也稱為回呼);服務藉由呼叫接續函式,以 JSON 格式傳回動態饋給。接著,用戶端可以呼叫各種 get 方法,以 JavaScript 物件的形式使用資料。

如要新增項目,您可以使用用戶端程式庫的類別和方法建立項目,然後呼叫 feed.insertEntry() 方法,將新項目傳送至服務。再次提供一個接續函式,當成功新增項目時,服務會呼叫該函式。

如果您是 JavaScript 新手,控制流程可能會有些許混淆。在多數情況下,在呼叫 getEventsFeed()insertEntry() 等方法後,指令碼就會結束。服務傳回要求的資料時,接續函式會繼續執行。因此,用戶端要針對傳回的資料執行的任何動作都應透過接續函式或該函式呼叫。您可能需要將這些變數設為全域,才能在多個函式中使用這些變數。

如要進一步瞭解這種程式設計,請參閱維基百科中的「通過傳遞樣式」。

關於支援的環境

目前,我們只支援在瀏覽器的網頁中執行的 JavaScript 用戶端應用程式。目前支援的瀏覽器如下:

  • Firefox 2.x 和 3.x
  • Internet Explorer 6、7 和 8
  • Safari 3.x 和 4.x
  • Google Chrome (所有版本)

JavaScript 用戶端程式庫會處理所有與服務伺服器之間的通訊。如果你是經驗豐富的 JS 開發人員,不妨思考「相同來源政策會有什麼影響?」JavaScript 用戶端程式庫可讓您的用戶端從任何網域傳送 Google 資料要求,同時仍符合瀏覽器的安全性模式。

如需使用 Google Data API 進行驗證的總覽,請參閱 Google Data API 驗證總覽。本文件的其他部分假設您已熟悉這個系統的運作方式。

用戶端應用程式範例

如要查看 JavaScript 用戶端程式庫的實際運作情形,請前往範例網頁

教學課程與範例

以下範例說明如何使用 JavaScript 用戶端程式庫傳送各種資料 API 要求。

為使實際而言更具體,這些範例說明瞭如何與特定服務互動:Google 日曆。我們會指出「Google 日曆」與其他 Google 服務的差異,協助您配合這些範例使用其他服務。如要進一步瞭解 Google 日曆,請參閱 Google Calendar Data API 文件。

載入程式庫

您的用戶端必須先從伺服器要求用戶端程式庫程式碼,方可使用用戶端程式庫。

首先,請在 HTML 文件的 <head> 區段中使用 <script> 標記來擷取 Google AJAX API 載入器:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

預先載入程式庫,可將往返行程降到最低,並縮短延遲時間。如要直接從 Google AJAX API 載入器預先載入特定套件 (不使用 google.load(),請見下方說明):

<script type="text/javascript"
      src="https://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A2.x%2Cpackages%3A%5Bblogger%2Ccontacts%5D%7D%5D%7D"></script>

注意:指令碼的 src 網址必須以完整網址進行編碼。例如,上述範例是
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script>

如果您未自動載入模組,您可以在擷取通用載入器後,使用 JavaScript 設定程式碼中的下一個範例來載入 Google Data 用戶端程式庫。此呼叫必須來自 HTML 文件的 <head> 區段 (或在您 HTML 文件的 <head> 區段中,使用 <script> 標記所附的 JavaScript 檔案):

google.load("gdata", "2");

此外,您也可以要求特定的服務,而非整個程式庫。這個範例只會下載 Blogger 和 Google 聯絡人的套件:

google.load("gdata", "2.x", {packages: ["blogger", "contacts"]});

google.load() 的第二個參數是 JavaScript 用戶端程式庫要求的版本號碼。我們的版本編號配置是採用 Google Maps API 使用的版本編號建立而成。以下是可能的版本編號及其代表:

"1"
主要版本 1 的次要版本。
"1.x"
主要版本 1 的最新版本。
"1.s"
主要版本 1 的最新穩定版本。根據開發人員收到的意見回饋,我們有時會將特定的用戶端程式庫版本宣告為「穩定版」。但這類穩定版本可能不提供最新功能。
"1.0""1.1" 等
程式庫的特定版本,具有指定的主要和次要修訂版本編號。

呼叫 google.load() 後,您必須指示載入器等待網頁載入完成,再呼叫程式碼:

google.setOnLoadCallback(getMyFeed);

其中 getMyFeed() 是指本文件下一節定義的函式。請使用這個方法,不要在 <body> 元素中附加 onload 處理常式。

要求未經驗證的資訊提供

如果想要求未經驗證的資訊提供,請在 JavaScript 檔案或 HTML 檔案的 <script> 標記中加入以下程式碼。

在下方程式碼中,系統會先呼叫 getMyFeed() (由上一節所述的 AJAX API 載入器)。

該呼叫會呼叫 setupMyService(),以建立與 Google 日曆的連線 (由 CalendarService 物件表示)。我們已將服務建立程式碼擷取到單獨的模組中;之後,我們將根據您的驗證選項來修改 setupMyService() 函式。

服務設定完畢後,getMyFeed() 會呼叫用戶端程式庫的 getEventsFeed() 方法來要求動態饋給。

我們要在全域變數中指定資訊提供網址,以便稍後用於函式。在這個範例中,我們使用名為 liz@gmail.com 的使用者的公開 (未經驗證) 資訊提供網址。您也可以使用 default 來取代使用者的電子郵件地址來代表已驗證的使用者。

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/public/full";

function setupMyService() {
  var myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
  return myService;
}

function getMyFeed() {
  myService = setupMyService();

  myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}

請注意,我們將 myService 設為全域變數,以便之後使用。

如要讓上述用戶端在上述用戶端正常運作,您必須使用公開使用者的電子郵件地址,以公開日曆共用日曆。

附註:當您建立新的 CalendarService 物件時,用戶端程式庫會呼叫名為 google.gdata.client.init() 的方法,檢查是否支援用戶端執行的瀏覽器。如果發生錯誤,用戶端程式庫就會將錯誤訊息向使用者顯示。如果您想自行處理這類錯誤,可以在建立服務前明確呼叫 google.gdata.client.init(handleInitError),其中 handleInitError() 是您的函式。如果 init 發生錯誤,則您的函式會收到標準的 Error 物件;您可以對該物件執行任何所需操作。

呼叫 getEventsFeed() 時,第二個引數為 handleMyFeed,也就是回呼函式;如下所示。Google 日曆會處理要求,如果要求成功,則會將內含要求資訊提供的「資訊提供根」物件傳送至回呼。動態饋給根目錄是包含動態饋給的容器物件。

getEventsFeed() 的第三個引數是選用的錯誤處理函式;如果用戶端程式庫發生錯誤,就會呼叫指定的錯誤處理常式,而不是成功的回呼函式。用戶端程式庫做為引數傳送至引數處理常式的物件為 JavaScript Error 物件的執行個體,以及額外的 cause 屬性。

以下是回呼函式和錯誤處理常式的簡易版本:

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}

function handleError(e) {
  alert("There was an error!");
  alert(e.cause ? e.cause.statusText : e.message);
}

我們會直接向使用者顯示錯誤,藉此處理錯誤;用戶端的錯誤處理常式可能較為複雜。在某些情況下,可能沒有指定任何原因,因此範例範例處理常式會改回顯示標準 message 屬性。

請注意,由於這組驗證碼不會進行驗證,因此您只能用於取得公開動態饋給。

驗證中

JavaScript 用戶端程式庫可在兩種模式下使用。編寫小工具時,該小工具會使用名為 OAuth Proxy 的功能進行驗證。如果應用程式是透過獨立的 JavaScript 應用程式存取,則會使用 AuthSub 驗證系統。如需驗證相關資訊,請參閱 Google Data API 驗證總覽文件。本節的其餘部分假設您已熟悉這個系統的運作方式。

使用本文件提供的程式碼範例進行驗證程序之前,請將資訊提供網址從公開變更為私人:

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/private/full";

使用 AuthSub 在網路用戶端進行驗證

Google 的「AuthSub for JavaScript」授權系統已無法使用。

因此,我們建議針對用戶端應用程式使用 OAuth 2.0

使用 OAuth Proxy 在小工具中驗證

以下簡單說明小工具驗證程序期間會發生的情況:

  1. 您的小工具第一次載入時,會嘗試使用其中一種 Google Data API 存取使用者資料。
  2. 使用者尚未授予其資料存取權,因此要求失敗。 回應物件含有 OAuth 核准頁面的網址 (response.oauthApprovalUrl)。您的小工具應提供以此網址啟動新視窗的方法。
  3. 在核准網頁上,使用者選擇以何種方式允許/拒絕存取您的小工具。如果成功,系統會將使用者帶往您指定的 oauth_callback 頁面。為了提供最佳使用者體驗,請使用 http://oauth.gmodules.com/gadgets/oauthcallback
  4. 接著,使用者關閉彈出式視窗。為協助通知小工具使用者已取得核准,我們提供彈出式視窗處理常式,可用來偵測核准視窗關閉情況。此外,您的小工具還可以顯示一個連結 (例如「我已核准存取」),使用者可在這個視窗關閉後手動點擊。
  5. 您的小工具會再次要求存取使用者資料,嘗試再次存取 Google Data API。嘗試成功。
  6. 您的小工具已通過驗證,可以正常執行。

在小工具的 <ModulePrefs> 區段中新增 <OAuth> 元素:

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?
                  scope=http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

在這個部分中,變更下列查詢參數:

  • scope

    要求網址中的必要參數。您的小工具只能存取這個參數中使用的 scope 資料。在這個範例中,小工具將存取您的 Blogger 和「Google 日曆」資料。小工具可以要求單一範圍或多個範圍的資料 (如本例所示)。

  • oauth_callback

    「授權網址」中的選用參數。使用者核准資料存取權後,OAuth 核准頁面將重新導向至這個網址。 您可以選擇放棄這項參數、將參數設為自己的「已核准網頁」,或是偏好使用「http://oauth.gmodules.com/gadgets/oauthcallback」。日後,當使用者首次安裝您的小工具時,即可提供最佳使用者體驗。這個網頁會提供一段會自動關閉彈出式視窗的 JavaScript 片段。

接下來,請在小工具的 <Content> 區段中載入 JavaScript 用戶端程式庫。修改之前範例的 setupMyService() 函式,以呼叫服務物件的 useOAuth() 方法。這可讓小工具使用 OAuth Proxy 進行驗證,而非 AuthSub。以下範本應該可協助您快速上手:

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    var myService = null;
    
    function setupMyService() {
      myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
      myService.useOAuth('google');
      fetchData();
    }
    
    function initGadget() {
      google.load('gdata', '2.x');
      google.setOnLoadCallback(setupMyService);
    }

    function fetchData() {            
      var callback = function(response) {
        if (response.oauthApprovalUrl) {
        
          // TODO: Display "Sign in" link (response.oauthApprovalUrl contains the URL) 
          
        } else if (response.feed) {
        
          // TODO: show results
          
        } else {
        
          // TODO: handle the error
          
        }
      };

      myService.getEventsFeed('http://www.google.com/calendar/feeds/default/public/full', callback, callback);
    }
    
    gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

請注意,已移除對 google.accounts.user.login(scope) 的呼叫。Proxy 會為您處理驗證作業。

如要進一步瞭解如何編寫 Google Data API 小工具,包括 fetchData() 應包含的內容詳細資訊,請參閱「建立 Google Data 小工具」一文,或參閱完整的撰寫 OAuth 小工具說明文件。

插入新項目

如要建立新的日曆活動,請修改 handleMyFeed() 函式的結尾來呼叫新函式,以繼續執行先前的範例:

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
  insertIntoMyFeed(myResultsFeedRoot);
}

在新函式中,先使用 CalendarEventEntry 建構函式來建立新項目。然後插入項目,為服務插入完成時呼叫的回呼。

function insertIntoMyFeed(feedRoot) {
  var newEntry = new google.gdata.calendar.CalendarEventEntry({
      authors: [{
        name: "Elizabeth Bennet",
        email: "liz@gmail.com"
      }],
      title: {
        type: 'text', 
        text: 'Tennis with Darcy'
      },
      content: {
        type: 'text', 
        text: 'Meet for a quick lesson'
      },
      locations: [{
        rel: "g.event",
        label: "Event location",
        valueString: "Netherfield Park tennis court"
      }],
      times: [{
        startTime: google.gdata.DateTime.fromIso8601("2007-09-23T18:00:00.000Z"),
        endTime: google.gdata.DateTime.fromIso8601("2007-09-23T19:00:00.000Z")
      }]
  });
  feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);
}

請注意,建構函式中使用的每個物件屬性名稱都符合該屬性所使用的 setter 方法的名稱。(而非比對對應的 JSON 欄位名稱)。

另請注意,您不能為 startTimeendTime 提供 ISO 8601 日期和時間字串,必須先透過 fromIso8601() 方法執行這類字串。

服務會傳回插入項目的複本做為 entryRoot 物件,並將該物件傳送至回呼:

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
}

要求特定項目

如要要求特定項目,請先修改 handleMyInsertedEntry() 函式以呼叫新的項目要求函式:

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
  requestMySpecificEntry(insertedEntryRoot.entry.getSelfLink().getHref());
}

以下程式碼可讓您要求您在上一個範例中插入的特定項目。

在這個系列的範例中,您不一定要擷取該項目,因為 Google 日曆已經傳回插入的項目,但是只要您知道項目的 URI,就可以套用相同的技巧。

function requestMySpecificEntry(entryURI) {
  myService.getEventsEntry(entryURI, handleMySpecificEntry, handleError);
}

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
}

此範例基本上與 getEventsFeed() 範例相同,只是我們呼叫服務的 getEventEntry() 方法以取得特定項目,而 URI 稍有不同,它使用「default」來代表已驗證使用者的主要日曆,它的結尾有項目 ID。

此外,我們之後必須能夠使用擷取到的項目,因此它會複製到全域變數。

搜尋項目

如要執行全文搜尋,請先修改 handleMySpecificEntry() 函式以呼叫新的搜尋函式:

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
  searchMyFeed();
}

如要擷取搜尋的第一個相符項目,請使用下列程式碼:

function searchMyFeed() {
  var myQuery = new google.gdata.calendar.CalendarEventQuery(feedUrl);
  myQuery.setFullTextQuery("Tennis");
  myQuery.setMaxResults(10);
  myService.getEventsFeed(myQuery, handleMyQueryResults, handleError);
}

function handleMyQueryResults(myResultsFeedRoot) {
  if (myResultsFeedRoot.feed.getEntries()[0]) {
    alert("The first search-match entry's title is: " + myResultsFeedRoot.feed.getEntries()[0].getTitle().getText());
  }
  else {
    alert("There are no entries that match the search query.");
  }
}

更新項目

如要更新現有項目,請先在 handleMyQueryResults() 的結尾加上一行,以呼叫新的更新函式:

  updateMyEntry();

然後使用以下程式碼。在這個範例中,我們會將先前擷取的項目標題 (在先前範例中名為 myEntryRoot 的全域物件中) 從舊文字 (「網球達人) 」變更為「重要會議」。

function updateMyEntry() {
  myEntryRoot.entry.getTitle().setText("Important meeting");
  myEntryRoot.entry.updateEntry(handleMyUpdatedEntry, handleError);
}

function handleMyUpdatedEntry(updatedEntryRoot) {
  alert("Entry updated. The new title is: " + updatedEntryRoot.entry.getTitle().getText());
}

如同所有的 Google 日曆方法,updateEntry() 方法會自動決定更新項目時使用的正確編輯 URI,因此您不必明確提供該 URI。

刪除項目

如要刪除更新的項目,請先在 handleMyUpdatedEntry() 中新增一行:

 deleteMyEntry(updatedEntryRoot);

然後使用以下程式碼:

function deleteMyEntry(updatedEntryRoot) {
  updatedEntryRoot.entry.deleteEntry(handleMyDeletedEntry, handleError);
}

function handleMyDeletedEntry() {
  alert("Entry deleted");
}

再次提醒您,deleteEntry() 方法會自動決定刪除該項目時使用的正確編輯 URI。

請注意,系統不會傳回任何項目。如果呼叫回呼,我們便會知道刪除成功;如果刪除失敗,則 deleteEntry() 會呼叫 handleError(),而不是呼叫 handleMyDeletedEntry()

使用 ETag

注意:ETag 只能與執行 Google Data Protocol v2.0 的服務搭配使用。

簡介

Google 資料 JavaScript 用戶端 2 版本支援 ETag。ETag 是指定特定項目特定版本的識別碼;在這兩種情況下,這種做法非常重要:

  • 執行「條件式擷取」,用戶端會要求項目,且只有在該項目自用戶端上次要求之後變更時,伺服器才會傳送項目。
  • 確保多位用戶端不會意外覆寫彼此的變更。Google Data API 會進行更新,而如果用戶端針對該項目指定舊的 ETag,就會遭到刪除。

ETag 有兩種類型:弱和強。弱 E- 一律以 W/ 開頭,例如:W/"D08FQn8-eil7ImA9WxZbFEw"。當項目變更時,我們不保證每個 ETag 都會發生變化,因此 HTTP 僅允許用於條件式擷取。強 ETag 可識別特定項目的特定版本,且可用於條件式擷取以及更新或刪除,避免覆寫其他用戶端的變更。有鑑於此,用戶端程式庫不會讓您傳送 弱 的 ETag 以及 更新 或 刪除 要求。

您可以在伺服器回應的兩個位置找到 ETag:

  • ETag HTTP 標頭中。
  • 在動態饋給/項目中,做為 gd:etag 屬性。

如果服務支援版本 2,每個動態饋給和項目物件都會有 getEtag() 方法來擷取 ETag 的值。

JavaScript 用戶端支援在要求中加入 ETag 的兩種方法。第一個是新的 opt_params 物件。在用戶端程式庫第 2 版中,所有 get/update/insert 函式都有新的 opt_params 參數。這個物件在提出要求時用於指定選用參數。雖然 'etag' 是唯一支援的選用參數 (但日後可能會加入其他參數)。例如,您可以將 ETag 新增至 GET 要求,如下所示:

var opt_params = {};
opt_params['etag'] = 'ETAG GOES HERE';
service.getFeed(uri, successHandler, errorHandler, opt_params);

您也可以在動態饋給/項目上呼叫 setEtag() 方法,藉此將 ETag 直接新增至動態饋給或項目物件。

如要進一步瞭解 ETag,請參閱 GData 通訊協定參考資料

使用 ETag 擷取資料

ETag 有助於縮短擷取資料時的頻寬和執行時間。您可以在透過 If-None-Match header: 的 GET 要求中加入 ETag

If-None-Match: ETAG GOES HERE

如果 ETag 與動態饋給或項目的目前版本相符,伺服器會傳回 304 NOT MODIFIED 回應和空白主體。否則,伺服器會傳回 200 OK 回應,以及動態饋給或項目資料。

您可以在提出要求時加入 'etag' 參數,以便在 JavaScript 用戶端使用 ETag:

var etag = feed.getEtag(); // Feed loaded from a previous request
var opt_params = {};
opt_params['etag'] = etag;
service.getFeed(feedUrl, successHandler, errorHandler, opt_params);

條件式擷取可搭配使用強而有力的 ETag。如果 ETag 相符,則呼叫錯誤處理常式將傳回 304 回應:

function successHandler(feedRoot) {
  // 200 response
  // Update UI to display updates
}

function errorHandler(errorObj) {
  if (errorObj.cause.getStatus() == 304) {
    // 304 response, do nothing
  }
  // otherwise the response is some other error
}

請參考條件式擷取使用 Blogger 的範例範例,查看在 JavaScript 用戶端中使用 ETag 的更實際範例。此範例以 5 秒為單位對 Blogger 進行輪詢,尋找網誌的更新。每當有變更,範例就會更新文章清單。

使用 ETag 更新及刪除資料

在更新/刪除要求中使用 ETag,可確保多位用戶端不會意外覆寫彼此的變更。在此情況下,If-Match 標頭會包含 ETag:

If-Match: ETAG GOES HERE

如果要求中的 ETag 與伺服器上的 ETag 相符,更新/刪除就會成功。但是,ETag 不符代表項目已變更,而更新/刪除失敗。在這種情況下,應用程式應要求新的資料執行個體,然後再次嘗試更新/刪除。

在某些情況下,您可能會想強制變更項目,而不需對項目進行其他變更。方法是將 * 傳遞至 If-Match 標頭:

If-Match: *

請注意,這麼做會覆寫其他用戶端所做的變更,因此請謹慎使用。

你只能更新/刪除含有強大 ETag 的項目。指定弱 ETag 會導致錯誤發生。為避免這種情況,JavaScript 用戶端不會在更新及刪除要求時設定微弱的 ETag。

ETag 的使用方式與條件擷取相同:

function updateData(entry, service) {
  var etag = entry.getEtag();
  var opt_params = {};
  opt_params['etag'] = etag; // Or use '*' to force an update.
  service.updateEntry(successHandler, errorHandler, opt_params);
}

function successHandler(response) {
  // Successful update
}

function errorHandler(errorObj) {
  // ERROR - Update failed. Could be due to an ETag mismatch, but check the
  // error message to make sure. An ETag error will be in the format:
  // Mismatch: etags = ["Qnc-fTVSLyp7ImA9WxJbFEsDRAw."], version = [1249675665358000]
}

更新時,您可以在兩個位置指定 ETag:

  1. 在項目本身,使用 getEtag()setEtag() 方法。
  2. 在標頭中使用 opt_params 物件 (如上所示)。

從先前的 GET 要求載入的項目已有 ETag 欄位。所以在 opt_params 物件中指定相同的 ETag 是多餘的。如果在項目內文和 opt_params 中指定了 ETag,則優先採用 opt_params 中的 ETag。這可能會造成混淆,因此如果您無法順利設定條件式更新,請務必同時檢查項目和 opt_params 物件的 ETag。

為了簡化操作,google.gdata.Entry 類別也有自己的 updateEntry()deleteEntry() 方法。如果項目類別已有 ETag,則您不需要將其加入要求中;用戶端程式庫會自動執行此作業。例如:

// entry was loaded from a previous request.  No need to specify
// an ETag in opt_params here, it is added automatically.
entry.deleteEntry(successHandler, errorHandler);

這樣您就能正確使用 ETag。不過,如果您想使用 '*' 強制更新,就必須一律在 'etag' = '*' 中加入 opt_params 物件。

您可以在「聯絡人」的條件式更新中查看工作狀態更新。此範例會先建立測試聯絡人群組,以在此範例中使用所有資料。完成取樣之後,歡迎刪除這個聯絡人群組。接著,範例會載入兩個含有聯絡人群組內容的 iframe。您可以在某個 iframe 中進行更新,看看這些巨集如何影響另一個 iframe 中的更新。歡迎造訪範例,進一步瞭解如何使用這項工具。

範例

參考資料

如需用戶端程式庫提供的類別和方法的參考資訊,請參閱 JavaScript 用戶端程式庫 API 參考資料 (JSdoc 格式)。

返回頁首