Использование клиентской библиотеки JavaScript (v2.0)

Предупреждение . Эта страница посвящена старым API Google, API данных Google; это относится только к API, которые перечислены в каталоге API данных Google , многие из которых были заменены более новыми API. Для получения информации о конкретном новом API см. документацию по новому API. Информацию об авторизации запросов с помощью более нового API см. в разделе Аутентификация и авторизация учетных записей Google .

В этом документе описывается, как использовать клиентскую библиотеку JavaScript для отправки запросов API данных Google и интерпретации возвращаемых ответов.

Google предоставляет набор клиентских библиотек на различных языках программирования для взаимодействия со службами, имеющими API данных. Используя эти библиотеки, вы можете создавать запросы API, отправлять их в службу и получать ответы.

Этот документ предоставляет некоторую общую информацию об использовании клиентской библиотеки JavaScript, а также набор примеров частого использования.

Аудитория

Этот документ предназначен для программистов JavaScript, которые хотят писать клиентские приложения, способные взаимодействовать со службами данных Google.

В этом документе предполагается, что вы понимаете общие идеи протокола API данных Google . Также предполагается, что вы умеете программировать на JavaScript.

Справочную информацию о классах и методах, предоставляемых клиентской библиотекой, см. в справочнике по API клиентской библиотеки JavaScript (в формате JSdoc).

Этот документ предназначен для чтения по порядку; каждый пример основан на более ранних примерах.

Условия эксплуатации

Вы соглашаетесь соблюдать Условия использования клиентской библиотеки JavaScript Google при использовании клиентской библиотеки JavaScript.

Обзор модели данных и потока управления

Клиентская библиотека JavaScript использует набор классов для представления элементов, используемых API данных Google.

Примечание . Базовым представлением данных является JSON, но клиентская библиотека предоставляет уровень абстракции, поэтому вам не нужно напрямую работать с данными JSON. Если вы хотите работать с JSON напрямую, без клиентской библиотеки, см. раздел Использование JSON с API данных Google .

Библиотека предоставляет методы, которые позволяют асинхронно отправлять данные и получать данные от службы, имеющей API данных. Например, метод google.gdata.calendar.CalendarService.getEventsFeed() отправляет запрос на ленту в Календарь Google. Один из параметров, которые вы передаете, является функцией продолжения, также известной как обратный вызов; служба возвращает фид в формате JSON, вызывая функцию продолжения. Затем клиент может вызывать различные методы get для использования данных в виде объектов JavaScript.

Чтобы добавить новую запись, вы создаете запись, используя классы и методы клиентской библиотеки, а затем вызываете метод feed.insertEntry() для отправки новой записи в службу. Вы снова предоставляете функцию продолжения, которую служба вызывает после успешного добавления записи.

Если вы новичок в JavaScript, поток управления может быть немного запутанным. После вызова такого метода, как getEventsFeed() или insertEntry() , в большинстве случаев ваш скрипт завершается. Выполнение возобновляется в функции продолжения, когда служба возвращает запрошенные данные. Следовательно, все, что ваш клиент делает с возвращенными данными, должно выполняться в функции продолжения или вызываться из этой функции. Вам может понадобиться сделать некоторые переменные глобальными, чтобы использовать их в нескольких функциях.

Дополнительные сведения об этом стиле программирования см. в статье « Стиль передачи продолжения » в Википедии.

О поддерживаемых средах

В настоящее время мы поддерживаем только клиентские приложения JavaScript, которые запускаются на веб-странице в браузере. В настоящее время поддерживаются следующие браузеры:

  • Фаерфокс 2.х и 3.х
  • Internet Explorer 6, 7 и 8
  • Сафари 3.х и 4.х
  • Google Chrome (все версии)

Клиентская библиотека JavaScript обрабатывает всю связь с сервером службы. Если вы опытный разработчик JS, вы можете подумать: «А как насчет той же политики происхождения ?» Клиентская библиотека JavaScript позволяет вашему клиенту отправлять запросы данных Google из любого домена, сохраняя при этом соответствие модели безопасности браузера.

Общие сведения об аутентификации с помощью API данных Google см. в разделе Обзор аутентификации API данных Google . Остальная часть этого документа предполагает, что вы знакомы с основами работы этой системы.

Примеры клиентских приложений

Чтобы увидеть клиентскую библиотеку JavaScript в действии, посетите нашу страницу с примерами .

Учебник и примеры

В следующих примерах показано, как отправлять различные запросы API данных с помощью клиентской библиотеки JavaScript.

Чтобы сделать их более конкретными, эти примеры показывают, как взаимодействовать с конкретной службой: Календарь Google. Мы укажем места, где Календарь отличается от других служб Google, чтобы помочь вам адаптировать эти примеры для использования с другими службами. Дополнительные сведения о Календаре см. в документе API данных Google Календаря .

Загрузка библиотеки

Прежде чем ваш клиент сможет использовать клиентскую библиотеку, он должен запросить код клиентской библиотеки с сервера.

Начните с использования тега <script> в разделе <head> вашего HTML-документа, чтобы получить загрузчик Google AJAX API:

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

Вы можете свести к минимуму обращения к серверам Google и уменьшить задержку, предварительно загрузив библиотеку. Чтобы предварительно загрузить определенные пакеты непосредственно из загрузчика 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>

Примечание . URL-адрес src сценария должен быть полностью закодирован. Например, предыдущий пример
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script> .

Если вы не используете автозагрузку модулей, вы можете загрузить клиентскую библиотеку данных Google, используя следующий пример в коде установки JavaScript после получения общего загрузчика. Этот вызов должен быть сделан из раздела <head> вашего HTML-документа (или из файла JavaScript, включенного с помощью тега <script> в раздел <head> вашего HTML-документа):

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

Кроме того, вы можете запросить определенные услуги вместо всей библиотеки. В этом примере загружаются только пакеты для Blogger и Contacts:

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() — это функция, определенная в следующем разделе этого документа. Используйте этот подход вместо того, чтобы прикреплять обработчик onload к элементу <body> .

Запрос фида без аутентификации

Чтобы запросить фид без аутентификации, добавьте следующий код в файл JavaScript или в тег <script> в файле HTML.

В следующем коде сначала вызывается getMyFeed() (загрузчиком AJAX API, как описано в предыдущем разделе).

Он вызывает setupMyService() для создания подключения (представленного объектом CalendarService) к Календарю Google. Мы вынесли код создания сервиса в отдельную функцию для модульности; позже мы изменим функцию setupMyService() в зависимости от вашего выбора аутентификации.

После настройки службы getMyFeed() вызывает метод клиентской библиотеки getEventsFeed() для запроса канала.

Мы указываем URL-адрес фида в глобальной переменной, чтобы его можно было использовать в последующих функциях. В этом примере мы используем общедоступный (не прошедший проверку подлинности) URL-адрес канала для пользователя с именем [email protected] . Вы также можете использовать default вместо адреса электронной почты пользователя, чтобы представить пользователя, прошедшего проверку подлинности.

var feedUrl = "http://www.google.com/calendar/feeds/[email protected]/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() — это ваша функция. Если возникает ошибка инициализации, ваша функция получает стандартный объект 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. Если к нему обращаются из автономного приложения JavaScript, оно использует систему аутентификации AuthSub . Сведения об аутентификации см. в документе Обзор аутентификации API данных Google . В оставшейся части этого раздела предполагается, что вы знакомы с основами работы этой системы.

Прежде чем использовать аутентификацию с помощью примера кода, представленного в этом документе, измените URL-адрес фида с общедоступного на частный:

var feedUrl = "http://www.google.com/calendar/feeds/[email protected]/private/full";

Аутентификация в веб-клиенте с помощью AuthSub

Система авторизации Google "AuthSub for JavaScript" больше не доступна.

Вместо этого мы рекомендуем использовать OAuth 2.0 для клиентских приложений .

Аутентификация в гаджете с помощью прокси-сервера OAuth

Вот краткий обзор того, что происходит в процессе аутентификации гаджета:

  1. Ваш гаджет загружается в первый раз и пытается получить доступ к данным пользователя с помощью одного из API данных Google.
  2. Запрос не выполняется, поскольку пользователь еще не предоставил доступ к своим данным. Объект ответа содержит URL-адрес (в response.oauthApprovalUrl ) страницы утверждения OAuth. В вашем гаджете должен быть предусмотрен способ запуска нового окна с этим URL-адресом.
  3. На странице одобрения пользователь может разрешить или запретить доступ к вашему гаджету. В случае успеха пользователь перенаправляется на указанную вами страницу oauth_callback . Для наилучшего взаимодействия с пользователем используйте http://oauth.gmodules.com/gadgets/oauthcallback .
  4. Далее пользователь закрывает всплывающее окно. Чтобы уведомить ваш гаджет о том, что пользователь дал разрешение, мы предоставили обработчик всплывающих окон , который можно использовать для обнаружения закрытия окна утверждения. Кроме того, ваш гаджет может отображать ссылку (например, " Я разрешил доступ "), чтобы пользователь мог нажать ее вручную после закрытия этого окна.
  5. Ваш гаджет пытается получить доступ к Google Data API во второй раз, повторно запрашивая данные пользователя. Эта попытка успешна.
  6. Ваш гаджет прошел проверку подлинности и может начать работать в обычном режиме.

В своем гаджете добавьте элемент <OAuth> в раздел <ModulePrefs> :

<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

    Обязательный параметр в URL-адресе запроса. Ваш гаджет сможет получить доступ к данным только из той scope (областей), которая используется в этом параметре. В этом примере гаджет получит доступ к вашим данным Blogger и Календаря. Гаджет может запрашивать данные для одной или нескольких областей (как в этом примере).

  • oauth_callback

    Необязательный параметр в URL-адресе авторизации. Страница утверждения OAuth будет перенаправлена ​​на этот URL-адрес после того, как пользователь подтвердит доступ к своим данным. Вы можете не указывать этот параметр, установить его на свою собственную «утвержденную страницу» или, что предпочтительнее, использовать http://oauth.gmodules.com/gadgets/oauthcallback . Последнее обеспечивает лучший пользовательский опыт, когда пользователи впервые устанавливают ваш гаджет. Эта страница содержит фрагмент javascript, который автоматически закрывает всплывающее окно.

Затем загрузите клиентскую библиотеку Javascript в разделе <Content> вашего гаджета. Измените функцию setupMyService() из предыдущих примеров, чтобы она вызывала метод useOAuth() объекта службы. Это указывает гаджету использовать для аутентификации прокси-сервер OAuth, а не 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) удален. Прокси обрабатывает аутентификацию для вас.

Для получения дополнительной информации о написании гаджетов Google Data API, в том числе сведений о том, что должен содержать fetchData() , см. нашу статью о создании гаджета данных Google или ознакомьтесь с полной документацией по написанию гаджетов 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: "[email protected]"
      }],
      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);
}

Обратите внимание, что имя каждого свойства объекта, используемого в конструкторе, совпадает с именем метода установки, используемого для этого свойства. (Вместо, например, сопоставления соответствующего имени поля JSON.)

Также обратите внимание, что вы не можете просто предоставить строки даты и времени ISO 8601 для startTime и endTime ; вы должны сначала запустить такие строки через метод 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());
}

Следующий код позволяет запросить конкретную запись, которую вы вставили в предыдущем примере.

В контексте этой серии примеров получение этой записи на самом деле не требуется, поскольку Calendar уже вернул вставленную запись; но тот же метод можно применять всякий раз, когда вы знаете 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 немного отличается — он использует «по умолчанию» для ссылки на основной календарь. для аутентифицированного пользователя и имеет идентификатор записи в конце.

Кроме того, нам нужно иметь возможность использовать полученную запись позже, поэтому мы копируем ее в глобальную переменную.

Поиск записей

Чтобы выполнить полнотекстовый поиск, сначала измените функцию 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());
}

Как и все методы Calendar, метод 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 версии 2.0.

Введение

Во второй версии клиента Google Data JavaScript появилась поддержка ETag. ETag — это идентификаторы, указывающие конкретную версию конкретной записи; это важно в двух случаях:

  • Выполнение «условного поиска», при котором клиент запрашивает запись, а сервер отправляет запись только в том случае, если запись изменилась с момента последнего запроса клиентом.
  • Обеспечение того, чтобы несколько клиентов случайно не перезаписали изменения друг друга. API данных делают это, делая обновления и удаления неудачными, если клиент указывает старый ETag для записи.

Есть два типа ETag: слабые и сильные. Слабый ETag всегда начинается с W/ , например: W/"D08FQn8-eil7ImA9WxZbFEw" . Нет гарантии, что слабые ETag изменятся при изменении записи, поэтому HTTP позволяет использовать их только для условного поиска. Сильные ETag идентифицируют конкретную версию конкретной записи и могут использоваться как для условного извлечения, так и во время обновлений или удалений, чтобы избежать перезаписи изменений других клиентов. Из-за этого различия клиентская библиотека не позволит вам отправлять слабые ETag с запросом на обновление или удаление.

ETags можно найти в двух местах в ответе сервера:

  • В HTTP-заголовке ETag .
  • В ленте/записи в качестве атрибута gd:etag .

Если сервис поддерживает Версию 2, каждый объект фида и записи будет иметь метод getEtag() для получения значения ETag.

Клиент JavaScript поддерживает два метода включения ETag в запрос. Первый — это новый объект opt_params . Все функции get/update/insert в версии 2 клиентской библиотеки имеют новый параметр opt_params . Этот объект используется для указания необязательных параметров при выполнении запроса. На данный момент единственным поддерживаемым необязательным параметром является 'etag' (хотя в будущем могут быть введены и другие параметры). Например, вы можете добавить ETag к GET-запросу следующим образом:

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

Вы также можете добавить ETag непосредственно к ленте или объекту записи, вызвав метод setEtag() для ленты/записи.

Вы можете узнать больше о ETags из Справочника по протоколу GData .

Использование ETag для получения данных

ETag могут помочь сократить пропускную способность и время выполнения при извлечении данных. ETag может быть включен в запрос GET с If-None-Match header:

If-None-Match: ETAG GOES HERE

Если ETag соответствует текущей версии фида или записи, сервер отвечает ответом 304 NOT MODIFIED и пустым телом. В противном случае сервер отвечает ответом 200 OK и фидом или входными данными.

Вы можете использовать ETags в клиенте 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 , чтобы увидеть более практичный пример использования ETag в клиенте JavaScript. Этот образец опрашивает Blogger с интервалом в 5 секунд в поисках обновлений вашего блога. При наличии изменений образец обновляет список сообщений.

Использование ETag для обновления и удаления данных

Использование ETag в запросах на обновление/удаление гарантирует, что несколько клиентов непреднамеренно не перезапишут изменения друг друга. В этом случае ETag включается в заголовок If-Match :

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. Поэтому указание одного и того же ETag в объекте opt_params излишне. В случае, когда ETag указан как в теле записи, так и в opt_params , ETag в opt_params будет иметь приоритет. Это может немного сбить с толку, поэтому, если у вас возникли проблемы с условными обновлениями, обязательно проверьте ETag как в записи, так и в объекте opt_params .

Чтобы упростить задачу, классы 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, не беспокоясь о том, правильно ли вы их установили. Однако, если вы хотите принудительно выполнить обновление с помощью '*' , вы всегда должны включать объект opt_params с 'etag' = '*' .

Вы можете увидеть условные обновления в работе в Условных обновлениях в Контактах. Образец сначала создает тестовую группу контактов, в которой будут созданы все данные, используемые этим образцом. Вы можете удалить эту контактную группу, когда закончите использовать образец. Затем образец загружает два окна iframe с содержимым из группы контактов. Вы можете вносить обновления в один iframe и смотреть, как это влияет на обновления в другом iframe. Посетите образец для получения более подробной информации о том, как его использовать.

Образцы

  • Условный поиск в Blogger . Опрашивает Blogger каждые 5 секунд и проверяет наличие обновлений.
  • Условное обновление в контактах — показывает два отдельных фрейма с данными контактов, поэтому вы можете воссоздать, как два клиента могут взаимодействовать при создании/обновлении/удалении контактов.

Ссылка

Справочную информацию о классах и методах, предоставляемых клиентской библиотекой, см. в справочнике по API клиентской библиотеки JavaScript (в формате JSdoc).

Вернуться к вершине