Uso de conteúdo remoto

Este documento descreve como obter e manipular dados remotos textuais (normalmente HTML), XML, JSON e de feeds RSS/Atom.

Sumário

  1. Introdução
  2. Uso de tipos de conteúdo diferentes
    1. Uso de texto
    2. Uso de XML
    3. Uso de feeds
    4. Uso de JSON
  3. Configuração de um tipo de autorização
  4. Métodos
    1. GET
    2. POST
  5. Atualização do cache

Introdução

A capacidade de combinar informações de diversas fontes de maneiras novas ou de fornecer meios alternativos de interação com informações existentes é um dos recursos mais empolgantes disponíveis para os gadgets. A API de gadgets permite que o gadget obtenha remotamente conteúdo de outros servidores e páginas da web e realize operações com esse conteúdo.

A API de gadgets fornece a função makeRequest(url, callback, opt_params) para recuperação e operação com conteúdo da web remoto. Ela aceita os seguintes argumentos:

  • String url - O URL no qual o conteúdo está localizado
  • Function callback - A função a ser chamada com os dados do URL após a obtenção
  • Map.<gadgets.io.RequestParameters, Object> opt_params - Parâmetros adicionais a serem passados para a solicitação.

Os argumentos opt_params permitem especificar:

  • O tipo de conteúdo da solicitação (TEXT, XML, FEED e JSON)
  • O tipo de método da solicitação (POST ou GET)
  • Qualquer cabeçalho que você deseje incluir na solicitação
  • O tipo de autorização (NONE, SIGNED e OAUTH )

Observação: Você não pode usar makeRequest() com gadgets type=''url''.

Independentemente do tipo de dados sendo obtidos, as chamadas a makeRequest() compartilham as mesmas características:

  • Seu primeiro parâmetro é um URL usado para obter o conteúdo remoto.
  • Seu segundo parâmetro é uma função de retorno de chamada, usada para processar os dados retornados.
  • Elas são assíncronas, ou seja, todo o processamento deve ocorrer dentro da função de retorno de chamada. Um retorno de chamada é uma função passada como parâmetro (na forma de uma referência de função) a outra função. Os retornos de chamada fornecem aos desenvolvedores um ''gancho'' que pode ser conectado a uma estrutura em execução para realizar processamentos.
  • Eles não têm valores de retorno porque são retornados imediatamente, e as funções de retorno de chamada a eles associadas são chamadas sempre que a resposta é retornada.

Por exemplo, pense no seguinte snippet de código, que obtém conteúdo remoto em forma de texto. Este código obtém o texto HTML da página da web google.com e exibe os primeiros 400 caracteres:

function getHtml() {    
  var params = {};  
  params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;  
  var url = "http://www.google.com";  
  gadgets.io.makeRequest(url, response, params);
};
function response(obj) {  
  //obj.text contains the text of the page that was requested  
  var str = obj.text;
  var html =  str.substr(0,400);  
  document.getElementById('content_div').innerHTML = html;
};
gadgets.util.registerOnLoadHandler(getHtml);

Este exemplo ilustra os princípios básicos do funcionamento da função makeRequest():

  1. Quando a função makeRequest() é chamada, a API de gadgets faz uma solicitação HTTP GET assíncrona ao URL passado para a função (neste exemplo, o URL é http://www.google.com).
  2. makeRequest() é retornada imediatamente e chama a função de retorno de chamada posteriormente (neste exemplo, denominada response()), quando todo o conteúdo é obtido. Isso significa que você deve colocar todos os códigos dependentes dentro da função de retorno de chamada ou dentro de funções chamadas pela função de retorno de chamada.
  3. makeRequest() retorna um objeto JavaScript com a seguinte estrutura:
{
  data : <parsed data, if applicable>,
  errors : <any errors that occurred>,
  text : <raw text of the response>  
}  

Este objeto é fornecido somente como o argumento para a função de retorno de chamada. A função de retorno de chamada executa algumas operações com os dados retornados. Normalmente, ela extrai partes dos dados, combina-os com markup HTML e exibe o HTML resultante no gadget.

Uso de tipos de conteúdo diferentes

Como padrão, o conteúdo de um site remoto é retornado como texto. Você pode usar o campo opt_params para definir o conteúdo retornado como um dos seguintes tipos:

  • TEXT -- gadgets.io.ContentType.TEXT
  • DOM -- gadgets.io.ContentType.DOM
  • FEED -- gadgets.io.ContentType.FEED
  • JSON -- gadgets.io.ContentType.JSON

Uso de texto

Aqui está um exemplo que obtém dados de um arquivo CSV (valores separados por vírgulas) e os utiliza para preencher uma lista de contatos pessoais. Ele mostra como definir o tipo do conteúdo obtido nos parâmetros opcionais. Na função response(obj) de retorno de chamada, o valor do texto é extraído de obj usando obj.text:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch Text Example"/>
  <Content type="html">
  <![CDATA[
  <div id="content_div"></div>
  <script type="text/javascript">

  // This example fetches data from a CSV file containing contact information. In the CSV file, 
  // each record consists of a name, email address, and phone number.
  function getContacts() {
    var params = {};  
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;  
    var url = "http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/Contacts.csv";
    gadgets.io.makeRequest(url, response, params);
  };
  // Callback function to process the response
  function response(obj) {               
    var responseText = obj.text;  
    // Set CSS for div.
    var html = "<div style='padding: 5px;background-color: #FFFFBF;font-family:Arial, Helvetica;" 
    + "text-align:left;font-size:90%'>"; 

    // Use the split function to extract substrings separated by comma 
    // delimiters.
    var contacts = responseText.split(",");
    // Process array of extracted substrings.
    for (var i = 0; i < contacts.length ; i++) {
      // Append substrings to html.
      html += contacts[i]; 
      html += " ";

      // Each record consists of 3 components: name, email, and
      // phone number. The gadget displays each record on a single
      // line:
      //
      // Mickey Mouse mickey@disneyland.com 1-800-MYMOUSE
      //
      // Therefore, insert a line break after each (name,email,phone)
      // triplet (i.e., whenever (i+1) is a multiple of 3).
      if((i+1)%3 ==0) { 
        html += "<br>";
      }
    }
    html += "</div>";
    // Output html in div.
    document.getElementById('content_div').innerHTML = html;
  }
  gadgets.util.registerOnLoadHandler(getContacts);

 </script>
  ]]>
  </Content>
</Module>

Uso de XML

O DOM (Document Object Model, Modelo de objeto de documento) é uma API para navegação em documentos HTML e XML. Você pode usar makeRequest() para recuperar um documento XML como um objeto DOM. Você pode operar o objeto obtido usando funções DOM JavaScript padrão. Normalmente, isso significa extrair os dados desejados do arquivo XML, combiná-los com markup HTML e CSS e exibir o HTML resultante em seu gadget.

Com o DOM, o conteúdo da web é analisado em uma árvore de nós. Por exemplo, veja o snippet de HTML abaixo:

<a href="http://www.google.com/">Google's <b>fast</b> home page.</a>

Este trecho ilustra os principais tipos de nós discutidos nesta seção:

  • Nós de elemento. Os nós de elemento deste snippet são “a” e “b”. Os nós de elemento são os blocos que definem a estrutura de um documento.
  • Nós de texto. Os nós de texto deste trecho são ‘Google’s’, ‘fast’ e ‘home page’. Os nós de texto são sempre inseridos em nós de elemento. Eles são os nós-filho do nó de elemento em que estão inseridos.
  • Nós de atributo. Este snippet apresenta um nó de atributo: href=’http://www.google.com’. Um nó de atributo fornece informações adicionais sobre o nó de elemento em que está inserido. Entretanto, os atributos não são considerados nós-filho dos elementos em que estão inseridos, o que afeta o modo como você trabalha com eles. Para ler mais sobre este tópico, consulte Uso de tipos de nó diferentes.

Esta é a estrutura DOM do snippet do HTML:

árvore DOM

Para acessar os dados de um objeto DOM você "percorre a árvore", usando funções DOM para navegar pelos relacionamentos de nó pai-filho e chegar aos dados necessários.

Exemplo

O arquivo XML abaixo contém dados para uma série de itens de café da manhã. O primeiro nó-pai é menu, que possui diversos nós-filho food. O nó menu também contém um nó de atributo: title=''Breakfast Menu". Cada nó food possui os nós-filho name, price, description e calories.

Os nós name, price e calories contêm seus próprios nós-filho de texto. Cada nó description contém um nó-filho CDATA. CDATA é um tipo distinto de nó. As seções CDATA são usadas para adicionar códigos de escape a blocos de texto contendo caracteres (como sinais de menor e maior) que, de outra forma, seriam considerados markup. O único separador reconhecido em uma seção CDATA é a string "]]>", que finaliza a seção CDATA.

<?xml version="1.0" encoding="UTF-8" ?>
<menu title="Breakfast Menu">
  <food>
     <name>Early Bird Breakfast</name> 
     <price>$3.95</price> 
     <description><![CDATA[<div style="color:purple; padding-left:25px;">Two eggs any style with your choice of bacon 
or sausage, toast or English muffin.</div>]]></description> 
     <calories>450</calories> 
  </food>

  <food>
     <name>Chocolate Chip Belgian Waffles</name> 
     <price>$7.95</price> 
     <description><![CDATA[<div style="color:purple; padding-left:25px;">Chocolate chip Belgian waffles covered with 
chocolate syrup and whipped cream.</div>]]></description> 
     <calories>900</calories> 
 </food>

     …
</menu>

O exemplo de gadget a seguir usa este arquivo XML como fonte de dados. Ele exibe um menu de café da manhã e permite que os usuários definam um limite de calorias. Ele exibe qualquer caloria acima do limite especificado em vermelho. Os usuários também podem selecionar se desejam exibir as descrições de cada item do café da manhã.

O código a seguir ilustra como percorrer a árvore DOM para extrair os dados dos diferentes tipos de nó, e como combiná-los a markup HTML e CSS para serem exibidos no gadget de menu de café da manhã.

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch XML" scrolling="true"/>
  <UserPref 
    name="mycalories" 
    display_name="Calorie limit" 
    default_value="800"/>
  <UserPref 
    name="mychoice" 
    display_name="Show Descriptions" 
    datatype="bool" 
    default_value="false"/>
  <Content type="html">
  <![CDATA[
    <div id="content_div"></div>
    <script type="text/javascript">
      // get prefs
      var prefs = new gadgets.Prefs();
      // Calorie limit set by user
      var calorieLimit = prefs.getString("mycalories");
      // Indicates whether to show descriptions in the breakfast menu    
      var description = prefs.getBool("mychoice");

      function makeDOMRequest() {    
        var params = {};  
        params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;  
        var url = "http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/breakfast-data.xml";  
        gadgets.io.makeRequest(url, response, params);
      };
      function response(obj) { 
        // Start building HTML string that will be displayed in <div>.           
        // Set the style for the <div>.        
        var html = "<div style='padding: 5px;background-color: #ccf;font-family:Arial, Helvetica;" 
          + "text-align:left;font-size:90%'>";   
        // Set style for title.
        html +="<div style='text-align:center; font-size: 120%; color: yellow; " 
          + "font-weight: 700;'>"; 
        // obj.data contains a Document DOM element corresponding to the
        // page that was requested
        var domdata = obj.data;

        // Display menu title. Use getElementsByTagName() to retrieve the <menu> element.
        // Since there is only one menu element in the file,
        // you can get to it by accessing the item at index "0". 
        // You can then use getAttribute to get the text associated with the
        // menu "title" attribute.
        var title = domdata.getElementsByTagName("menu").item(0).getAttribute("title");

        // Alternatively, you could retrieve the title by getting the menu element node
        // and calling the "attributes" function on it. This returns an array
        // of the element node's attributes. In this case, there is only one
        // attribute (title), so you could display the value for the attribute at
        // index 0. For example:
        // 
        // var title = domdata.getElementsByTagName("menu").item(0).attributes.item(0).nodeValue; 

        html += title + "</div><br>"; 
        // Get a list of the <food> element nodes in the file
        var itemList = domdata.getElementsByTagName("food");
 
        // Loop through all <food> nodes
        for (var i = 0; i < itemList.length ; i++) { 
        // For each <food> node, get child nodes.
        var nodeList = itemList.item(i).childNodes;

        // Loop through child nodes. Extract data from the text nodes that are
        // the children of the associated name, price, and calories element nodes.
        for (var j = 0; j < nodeList.length ; j++) {
          var node = nodeList.item(j);
          if (node.nodeName == "name") 
          {
            var name = node.firstChild.nodeValue;
          }
          if (node.nodeName == "price") 
          {
            var price = node.firstChild.nodeValue;
          }
          if (node.nodeName == "calories") 
          {
            var calories = node.firstChild.nodeValue; 
          }
          // If the user chose to display descriptions and
          // the child node is "#cdata-section", grab the 
          // contents of the description CDATA for display.
          if (node.nodeName == "description" && description==true)
          {
            if (node.firstChild.nodeName == "#cdata-section") 
              var data = node.firstChild.nodeValue;
          }
        } 
        // Append extracted data to the HTML string.
        html += "<i><b>";
        html += name;
        html += "</b></i><br>";
        html += "&emsp;"; 
        html += price;
        html += " - ";
        // If "calories" is greater than the user-specified calorie limit,
        // display it in red.
        if(calories > calorieLimit) {
          html += "<font color=#ff0000>";
          html += calories + " calories";
          html += " </font>"; 
        }
        else
          html += calories + " calories";
        html += "<br>";
        // If user has chosen to display descriptions
        if (description==true) 
        {
          html += "<i>" + data + "</i><br>";
        } 
      } 
      // Close up div
      html += "</div>";
      document.getElementById('content_div').innerHTML = html;
    };
    gadgets.util.registerOnLoadHandler(makeDOMRequest);
    </script>
  ]]>
  </Content>
</Module>

Esta amostra de código ilustra quatro das principais funções usadas para interagir com dados DOM:

  • getElementsByTagName(tagname)-- Para um documento DOM, retorna uma matriz dos nós de elemento cujos nomes correspondem a tagname. Você pode recuperar todos os nós de elemento de um arquivo usando o caractere curinga (*), por exemplo: response.getElementsByTagName("*").
  • getElementById(id)-- Para um documento DOM, recupera um único nó por id.
  • getAttribute(attrib)-- Para um nó de elemento, retorna o atributo attrib. Por exemplo: response.getElementsByTagName("menu").item(0).getAttribute("title").
  • attributes -- Para um nó de elemento, retorna uma matriz dos atributos do nó.

Este exemplo mostra somente algumas das diferentes funções para a navegação em uma árvore DOM. Experimente algumas das outras funções que você usar, como lastChild, nextSibling, previousSibling e parentNode.

Uso de tipos de nó diferentes

A chave para usar DOM de forma eficaz é compreender que, às vezes, há diferenças sutis entre diferentes tipos de nó.

Tipo de nó Descrição Valores retornados Armadilhas
element Os blocos estruturais de um documento, como <p> , <b> ou <calories>. nodeName: Qualquer texto entre os sinais de menor e maior. Por exemplo, o nodeName de <menu> é “menu”.

nodeType: 1

nodeValue : null
Um elemento tem nodeValue null. Para obter o valor de um nó de texto ou atributo associado a um elemento, é necessário ir para esses nós. Por exemplo: element.firstChild.nodeValue para texto e element.getAttribute(attrib) para atributos.
text Texto. Um nó de texto é sempre inserido em um nó de elemento. Ele é filho do elemento. nodeName: #text

nodeType: 3

nodeValue: Qualquer texto inserido no nó.
Alguns navegadores exibem todos os espaços em branco de um documento como nós de texto. Assim, seu objeto DOM irá conter nós de texto "vazios". Isso poderá gerar resultados inesperados quando você percorrer a árvore. Para solucionar esse problema, basta filtrar os nós de texto que contêm somente o caractere de nova linha. Ou você pode realizar uma manipulação mais robusta. Para ler mais sobre este tópico, consulte Espaços em branco no DOM.
attribute Um par de chave-valor que fornece informações adicionais sobre um nó de elemento (por exemplo, title=”my document”). Um atributo é inserido em um nó de elemento, mas não é filho do nó de elemento. nodeName: O valor à esquerda do par de atributo. Se o atributo for title=”my document”, nodeName será title.

nodeType: 2

nodeValue: O valor à direita do par de atributo (neste exemplo, “my document”).
Embora os atributos sejam nós e estejam inseridos em nós de elemento, eles não são nós-filho do elemento. Eles são herdados da interface de Node, mas o DOM não os considera parte da árvore DOM. Isso significa que, embora você possa usar muitas das funções de nó com os nós de atributo (como nodeName, nodeValue e nodeType), não é possível acessar nós de atributo usando as funções de navegação da árvore DOM. Para acessar os atributos, use as funções attributes e getAttribute(attrib).
CDATA Uma seção na qual o conteúdo não é manipulado ou interpretado. As seções CDATA são usadas para adicionar códigos de escape a blocos de texto contendo caracteres que, de outra forma, seriam considerados markup. O único separador reconhecido em uma seção CDATA é a string '']]>'', que finaliza a seção CDATA. nodeName: #cdata-section

nodeType: 4

nodeValue: Texto e markup dentro dos separadores CDATA.

O texto da seção CDATA tem seu próprio markup. Isso pode afetar o modo como você irá incorporá-lo ao gadget.
Outros recursos

Uso de feeds

Adicione um feed à sua página do iGoogle digitando seu URL no formulário Add by URL (Adicionar por URL) do diretório de conteúdo. Esse formulário utiliza o suporte integrado da API de gadgets para criar um gadget para o feed e adicioná-lo ao iGoogle. É fácil de usar, mas não permite qualquer personalização do conteúdo ou da exibição. Além disso, você não pode usá-lo com outros recipientes.

Para obter uma manipulação de feed mais sofisticada, você pode usar o método makeRequest() e especificar um tipo de conteúdo FEED. As solicitações de feed tentam analisar feeds xml ATOM ou RSS e retornar a resposta como um objeto codificado JSON.

Com um tipo de conteúdo FEED, você pode especificar os seguintes parâmetros:

Parâmetro Tipo de dados Descrição
gadgets.io.RequestParameters.NUM_ENTRIES Número, opcional O número de entradas de feed a serem recuperadas do feed. O intervalo aceito é de 1 a 100. O padrão é 3.
gadgets.io.RequestParameters.GET_SUMMARIES Booleano, opcional Mostra se deve recuperar os resumos completos de texto das entradas no feed. O padrão é falso. Você deve definir isso como verdadeiro apenas se planeja usar os dados. Os resumos completos podem ser um pouco grandes e não devem ser transferidos sem necessidade.

Aqui estão os campos no objeto do feed JSON:

Campo Descrição
ErrorMsg Se for definido, descreve qualquer erro ocorrido.
URL O URL do feed RSS/Atom.
Title O título do feed.
Description A tagline ou descrição do feed.
Link Normalmente, o URL da página inicial do feed.
Author O autor do feed.
Entry Matriz de entradas de feed. Os seguintes campos são aninhados na Entrada:
  • Title. O título da entrada deste feed.
  • Link. O URL da entrada deste feed.
  • Summary. O conteúdo ou resumo da entrada deste feed.
  • Date. Carimbo de data e hora desta entrada em segundos desde 1 de janeiro de 1970. Para convertê-lo nos milissegundos necessários para inicializar o objeto Date JavaScript com a data correta, multiplique por 1000. Consulte o código do exemplo de gadget abaixo para obter um exemplo.

Por exemplo, considere este feed RSS:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<rss version="2.0">
<channel>
<title>Code Examples for makeRequest()</title>
<link>http://code.google.com/apis/gadgets/docs/remote-content.html</link>
<description>This feed lists code examples for the gadgets.* makeRequest() function.</description>
<language>en</language>
<item>
<title>Fetch Text Example</title>
<link>http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/fetch-csv.xml</link>
<description>This example illustrates how to use makeRequest() with text content.</description>
<author>Google</author>
<pubDate>Sat, 09 Aug 2008 11:46:09 UT</pubDate> </item>
<item>
<title>Fetch XML Example</title>
<link>http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/fetch-XML.xml</link>
<description>This section describes how to use makeRequest() with XML content.</description>
<author>Google</author>
<pubDate>Sat, 09 Aug 2008 11:46:09 UT</pubDate>
</item>
<item>
<title>Feed Fetch Example</title>
<link>http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/feed-fetch.xml</link>
<description>This example illustrates how to use makeRequest() with Feed content.</description>
<author>Google</author>
<pubDate>Sat, 09 Aug 2008 10:33:09 UT</pubDate>
</item>
<item>
<title>Fetch JSON Example</title>
<link>http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/fetch-json.xml</link>
<description>This example illustrates how to use makeRequest() with JSON content.</description>
<author>Google</author>
<pubDate>Sat, 09 Aug 2008 03:55:28 UT</pubDate> </item>
</channel>
</rss>

Se você obtiver o feed acima com o tipo de conteúdo FEED, o valor retornado será codificado como uma string JSON da seguinte forma:

{"Entry":
  [
    {
      "Link":"http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/fetch-csv.xml",
      "Date":1218282369000,
      "Title":"Fetch Text Example",
      "Summary":"This example illustrates how to use makeRequest() with text content."
    },
    {
      "Link":"http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/fetch-XML.xml",
      "Date":1218282369000,
      "Title":"Fetch XML Example",
      "Summary":"This section describes how to use makeRequest() with XML content."
    },
    {
      "Link":"http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/feed-fetch.xml",
      "Date":1218277989000,
      "Title":"Feed Fetch Example",
      "Summary":"This example illustrates how to use makeRequest() with Feed content."
    },
    {
      "Link":"http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/fetch-json.xml",
      "Date":1218254128000,
      "Title":"Fetch JSON Example",
      "Summary":"This example illustrates how to use makeRequest() with JSON content."
    }
  ],
  "Description":"This feed lists code examples for the gadgets.* makeRequest() function.",
  "Link":"http://code.google.com/apis/gadgets/docs/remote-content.html",
  "Author":"Google",
  "URL":"http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/sample-gadgets-feed.xml",
  "Title":"Code Examples for makeRequest()"
}
    

O exemplo a seguir ilustra como usar a função makeRequest() para obter um feed e exibir partes de seus dados em um gadget. Aqui está o gadget. Ele obtém um feed que contém entradas do fórum de desenvolvedores de gadgets. Ele permite que os usuários especifiquem:

  • O número de entradas exibidas
  • Se o gadget deve exibir a data de cada entrada
  • Se o gadget deve exibir um resumo de cada entrada

Este é o código do exemplo:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch Feed Example" 
    title_url="http://groups.google.com/group/Google-Gadgets-API" 
    scrolling="true">
  </ModulePrefs>
  <UserPref name="show_date" display_name="Show Dates?" datatype="bool" default_value="false"/>
  <UserPref name="num_entries" display_name="Number of Entries:" default_value="5"/>
  <UserPref name="show_summ" display_name="Show Summaries?" datatype="bool" default_value="false"/>
  <Content type="html">
  <![CDATA[
  <style> #content_div { font-size: 80%;  margin: 5px; background-color: #FFFFBF;} </style>
  <div id="content_div"></div>
  <script type="text/javascript">

  // Get userprefs
  var prefs = new gadgets.Prefs();
  var showdate = prefs.getBool("show_date");
  var entries = prefs.getInt("num_entries");
  var summaries = prefs.getBool("show_summ");

  function getFeed() {  
    var params = {};  
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.FEED;  
    params[gadgets.io.RequestParameters.NUM_ENTRIES] = new Number(entries);  
    params[gadgets.io.RequestParameters.GET_SUMMARIES] = summaries; 
    var url = "http://groups.google.com/group/Google-Gadgets-API/feed/rss_v2_0_msgs.xml";  
    gadgets.io.makeRequest(url, response, params);
  };

  function response(obj) { 
    // obj.data contains the feed data
    var feed = obj.data;
    var html = "";

    // Display the feed title and description
    html += "<div><b>" + feed.Title + "</b></div>";
    html += "<div>" + feed.Description + "</div><br>";
      
    // Access the data for a given entry
    if (feed.Entry) {
      for (var i = 0; i < feed.Entry.length; i++) {
        html += "<div>"
          + "<a target='_blank' href='" + feed.Entry[i].Link + "'>"
          + feed.Entry[i].Title
          + "</a> ";
        if (showdate==true)
        { 
          // The feed entry Date field contains the timestamp in seconds
          // since Jan. 1, 1970. To convert it to the milliseconds needed
          // to initialize the JavaScript Date object with the correct date, 
          // multiply by 1000.
          var milliseconds = (feed.Entry[i].Date) * 1000; 
          var date = new Date(milliseconds); 
          html += date.toLocaleDateString();
          html += " ";
          html += date.toLocaleTimeString(); 
        }
        if (summaries==true) { 
          html += "<br><i>" + feed.Entry[i].Summary + "</i>";
        }
        html += "</div>";
      }
    }        
    document.getElementById('content_div').innerHTML = html;
  };
  gadgets.util.registerOnLoadHandler(getFeed);
  </script>
  ]]>
  </Content>
</Module>

Uso de JSON

JSON (JavaScript Object Notation) é um formato de intercâmbio de dados que permite codificar determinados tipos de objetos (matrizes e coleções de pares de chave e valor) na forma de strings que podem ser facilmente transmitidas. Use o tipo de conteúdo JSON para obter conteúdo com codificação JSON em forma de objeto JavaScript.

O gadget descrito abaixo obter o conteúdo de um arquivo de texto que contém a seguinte string em codificação JSON:

{"Name" : "Rowan", "Breed" : "Labrador Retriever", "Hobbies" : ["fetching", "swimming", "tugging", "eating"]}

Ao obter o conteúdo do arquivo de texto que contém essa string, o valor retornado é um objeto JavaScript contendo pares de chave e valor (ou seja, uma matriz associativa). Esta amostra recupera o objeto e imprime os pares de chave e valor nele contidos: Se o valor for uma matriz (conforme indicado por colchetes []), ele transformará os conteúdos da matriz em uma lista com marcadores:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Fetch JSON Example"/>
  <Content type="html">
  <![CDATA[
    <div id="content_div"></div>
    <script type="text/javascript">

    function makeJSONRequest() {    
      var params = {};
      params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
      // This URL returns a JSON-encoded string that represents a JavaScript object
      var url = "http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/json-data.txt";
      gadgets.io.makeRequest(url, response, params);
    };

    function response(obj) { 
      var jsondata = obj.data;
      var html = "";
      // Process returned JS object as an associative array
      for (var key in jsondata) {
        var value = jsondata[key];
        html += key + ": ";
        // If 'value' is an array, render its contents as a bulleted list
        if (value instanceof Array)
        {
          html += "<br /><ul>";
          for (var i = 0; i < value.length ; i++)
          {
            html += "<li>"+ jsondata.Hobbies[i] + "</li>";
          }
          html+= "</ul>";
        }  
        // If 'value' isn't an array, just write it out as a string
        else {        
          html += value + "<br />";
        }      
      }               
      document.getElementById('content_div').innerHTML = html;
     };
     gadgets.util.registerOnLoadHandler(makeJSONRequest);
     </script>
  ]]>
  </Content>
</Module>

Esta é a saída do gadget:

Nome: Rowan
Raça: Labrador Retriever
Hobbies:

  • brincar de buscar
  • nadar
  • puxar
  • comer

Mais informações sobre JSON

A API de gadgets fornece o método gadgets.json.stringify() de codificação de objetos como as strings JSON e o método gadgets.json.parse() para transformar uma string JSON em um objeto. Como o OpenSocial executa escape HTML automático em todos os dados retornados, incluindo os dados de aplicativos, é necessário desfazer o escape dos objetos JSON disponíveis na forma de strings no armazenamento de dados do aplicativo antes de analisá-los. Por exemplo: gadgets.util.unescapeString(jsondata).

Este exemplo cria uma matriz JavaScript, codifica-a como uma string JSON e converte a string JSON de volta em um objeto matriz:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="JSON Example" />
  <Content type="html">
  <![CDATA[
     <div id="content_div"></div>
     <script type="text/javascript">
     var html = "";
     // Create Array object
     var myfriends = new Array();
     myfriends[0] = "Touki";
     myfriends[1] = "Rowan";
     myfriends[2] = "Trevor";

     // Encode array as JSON string
     var jsonString = toJSON(myfriends);
     html += "The JSON string is " + jsonString + "<br />";
     html += "The type of jsonString is " + typeof(jsonString) + "<br />";

     // Convert JSON string back to an object
     var arr_obj = toObject(jsonString);
     html += "The type of arr_obj is " + typeof(arr_obj);
     document.getElementById('content_div').innerHTML = html;

     // Encode object as JSON string
     function toJSON(obj) { 
       return gadgets.json.stringify(obj); 
     }

     // Convert JSON string into an object
     function toObject(str) {
       return gadgets.json.parse(str);
    }
    </script>
  ]]>
  </Content>
</Module>

Veja como fica a saída deste gadget:

The JSON string is Touki","Rowan","Trevor
The type of jsonString is string
The type of arr_obj is object

Configuração de um tipo de autorização

A API de gadgets suporta os seguintes tipos de autorização:

  • gadgets.io.AuthorizationType.OAUTH (o recipiente usa o protocolo OAuth)
  • gadgets.io.AuthorizationType.SIGNED (a solicitação é assinada pelo recipiente)
  • gadgets.io.AuthorizationType.NONE (padrão)

O modo de usar estes métodos depende do recipiente. Aqui está um exemplo de como usar um tipo de autorização assinada específica do orkut. Para ver uma discussão sobre o uso de OAuth nos gadgets, consulte Criação de gadgets OAuth.

Métodos

A função makeRequest() permite a escolha entre os métodos HTTP GET e POST.

GET

Normalmente, GET é utilizado para recuperar informações de um site da web. O método GET é o modo padrão para a função makeRequest(), mas você pode realizar uma solicitação GET explícita da seguinte maneira:

function makeGETRequest(url) {
   var params = {};
   params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
   gadgets.io.makeRequest(url, response, params); 
};
function response(obj) {
   alert(obj.text); 
};
makeGETRequest("http://example.com"); 

Para transmitir parâmetros ao seu servidor na solicitação GET, basta anexá-los à string de consulta no momento da solicitação:

makeGETRequest("http://example.com?param1=12345&param2=hello"); 

POST

As solicitações POST normalmente são utilizadas para transmitir dados a um servidor com o intuito de modificar ou excluir registros. Em uma solicitação POST, você pode transmitir quantidades de dados maiores do que normalmente é possível em uma solicitação GET.

Utilize o código a seguir para realizar um POST:

function makePOSTRequest(url, postdata) {
   var params = {};
   postdata = gadgets.io.encodeValues(postdata);
   params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
   params[gadgets.io.RequestParameters.POST_DATA]= postdata;
   gadgets.io.makeRequest(url, response, params); 
};
function response(obj) {
   output(obj.text); 
};
var data = {   data1 : "test",   data2 : 123456 }; 
makePOSTRequest("http://example.com", data); 

Além de especificar o MÉTODO (METHOD) em opt_params para esta solicitação, especifique um parâmetro sob a chave gadgets.io.RequestParameters.POST_DATA. A codificação padrão para POST é application/x-www-form-urlencoded. Isso significa que o valor do parâmetro POST_DATA deve ser uma série de pares de chave/valor urlencoded, unidos por E comercial (&). A função gadgets.io.encodeValues existe para facilitar a conversão de objetos de dados neste formato. encodeValues aceita um objeto JavaScript e retorna uma string codificada adequada ao parâmetro POST_DATA.

Por exemplo, execute:

var data = {   data1 : "test",   data2 : 123456 };  gadgets.io.encodeValues(data); 

para gerar a string:

data1=test&data2=123456 

Esta string pode ser transmitida diretamente como valor de gadgets.io.RequestParameters.POST_DATA.

Atualização do cache

Se estiver usando a função makeRequest() para obter conteúdo atualizado mais de uma vez por hora, como dados de feeds, pode ser que você não obtenha as últimas atualizações. Isso ocorre porque seus resultados são armazenados em cache para tornar a execução do gadget mais rápida. Se você quiser ter certeza de que o gadget obteve os dados mais recentes, use o parâmetro refreshInterval para ignorar o cache e forçar uma atualização no intervalo que você especificar. Em outras palavras, o cache é atualizado a cada X segundos, onde X = refreshInterval.

Como padrão, as chamadas à função makeRequest são armazenadas em cache. No exemplo abaixo, a função wrapper usa os mesmos parâmetros da chamada à função makeRequest, mas aceita outro parâmetro denominado refreshInterval, que permite especificar a duração do cache.

function makeCachedRequest(url, callback, params, refreshInterval) {
  var ts = new Date().getTime();
  var sep = "?";
  if (refreshInterval && refreshInterval > 0) {
    ts = Math.floor(ts / (refreshInterval * 1000));
  }
  if (url.indexOf("?") > -1) {
    sep = "&";
  }
  url = [ url, sep, "nocache=", ts ].join("");
  gadgets.io.makeRequest(url, response, params);
}

O uso de cache tem uma finalidade específica. Tome cuidado para não atualizar o cache com muita freqüência, para não prejudicar o desempenho. O uso de cache agiliza a obtenção de dados. Ele também reduz a carga sobre os servidores de terceiros que hospedam o conteúdo remoto. Evite desativar o cache completamente (o que é feito usando-se o valor refreshInterval: 0). Se o gadget estiver recebendo milhões de visualizações de página por dia e enviando milhões de solicitações a estes servidores, desativar o cache não apenas afetará negativamente o desempenho do gadget de maneira negativa, mas também poderá sobrecarregar os servidores que fornecem dados ao seu gadget.

Como o padrão é atualizar o conteúdo a cada hora, o ideal é especificar um intervalo menor que uma hora. O intervalo recomendado para refreshInterval é mais de 60 e menos de 3.600.

Voltar ao início