aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/api/cache/index.html
blob: 9647fb506e67220d8326145e07cbf9a9aec18c3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
---
title: Cache
slug: Web/API/Cache
tags:
  - API
  - Armazenamento
  - Cache
  - Experimental
  - Interface
  - Offline
  - Rascunho
  - Referencia
  - Service Workers
translation_of: Web/API/Cache
---
<p>{{APIRef("Service Workers API")}}{{SeeCompatTable}}</p>

<p>A interface de <strong>Cache</strong> provê um mecanismo de pares de objeto <a href="http://fetch.spec.whatwg.org/#request">Request</a> / <a href="http://fetch.spec.whatwg.org/#response">Response</a> que estão cacheados, por exemplo, como parte do ciclo de vida de um {{domxref("ServiceWorker")}}. Note que a interface do <code>Cache</code> é exposta a escopos de janela como também aos workers. Você não precisa utiliza-la em conjunto com os service workers em si, mesmo que ela esteja definida na especificação dos mesmos.</p>

<p>Uma origem pode ter múltiplos objetos de <code>cache</code> nomeados. Você é o responsável por implementar como seu script (por exemplo, em um {{domxref("ServiceWorker")}}) trata uma atualização deste <code>Cache</code>. Itens em um <code>Cache</code> não são atualizados a não ser que explicitamente comandados para fazer tal coisa, também não expiram a não ser quando são deletados. Use {{domxref("CacheStorage.open", "CacheStorage.open(cacheName)")}} para abrir um <code>Cache</code> nomeado específico e depois chame qualquer um dos métodos presentes no <code>Cache</code> para manter os objetos cacheados.</p>

<p>Você é também o responsavel por, periódicamente, limpar as entradas de cache. Cada browser tem um limite fixo do tamanho de armazenamento de cache que cada origem pode utilizar. O browser faz o melhor que pode para gerenciar o espaço em disco, mas ele pode deletar um cache que não devia. Ele também vai, geralmente, deletar todos os dados de uma origem ou nenhum dado da mesma, nunca haverá uma ocasião não atômica onde o browser delete parcialmente os dados.</p>

<p>Certifique-se de versionar seus caches por nome e usar somente os caches nas versões do script que eles podem seguramente operar. Veja também o artigo sobre <a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker_API/Using_Service_Workers#Deleting_old_caches">remoção de caches antigos</a> para mais informações.</p>

<div class="note">
<p><strong>Nota</strong>: Implementações iniciais do Cache (tanto no Blink quando no Gecko) resolvem promises de {{domxref("Cache.add")}}, {{domxref("Cache.addAll")}}, e {{domxref("Cache.put")}} somente quando o corpo completo da resposta foi armazenado. Versões mais recentes desta especificação possuem uma melhora de linguagem informando que o browser pode resolver a promise assim que a entrada é registrada no banco de dados, mesmo que o corpo da resposta ainda esteja sendo enviado.</p>
</div>

<div class="note">
<p><strong>Nota</strong>: O algoritmo de comparação de chaves depende do <a href="https://www.fastly.com/blog/best-practices-for-using-the-vary-header">cabeçalho VARY</a> no valor. Então, comparar uma nova chave depende tanto de olhar para o valor e para a própria chave para novas entradas no cache.</p>
</div>

<div class="note">
<p><strong>Nota:</strong> A API de cache não segue os padrões HTTP de cabeçalhos de Cache.</p>
</div>

<h2 id="Métodos">Métodos</h2>

<dl>
 <dt>{{domxref("Cache.match", "Cache.match(request, options)")}}</dt>
 <dd>Retorna uma {{jsxref("Promise")}} que resolve para a resposta associada com a primeira requisição encontrada no objeto {{domxref("Cache")}}.</dd>
 <dt>{{domxref("Cache.matchAll", "Cache.matchAll(request, options)")}}</dt>
 <dd>Retorna uma {{jsxref("Promise")}} que resolve para um array com todas as referências encontradas de requisições presentes no objeto {{domxref("Cache")}}.</dd>
 <dt>{{domxref("Cache.add", "Cache.add(request)")}}</dt>
 <dd>Pega a URL, obtém o resultado da resposta e adiciona o mesmo no cache informado. Esta funcionalidade é equivalente a chamar <code>fetch()</code>, e depois utilizar <code>Cache.put()</code> para adicionar o resultado no cache.</dd>
 <dt>{{domxref("Cache.addAll", "Cache.addAll(requests)")}}</dt>
 <dd>A partir de um array de URL's, obtém as respostas e adiciona todos os objetos resultantes no cache informado.</dd>
 <dt>{{domxref("Cache.put", "Cache.put(request, response)")}}</dt>
 <dd>Dado uma requisição e uma resposta, adiciona ambas ao cache informado.</dd>
 <dt>{{domxref("Cache.delete", "Cache.delete(request, options)")}}</dt>
 <dd>Encontra a entrada do {{domxref("Cache")}} na qual a chave é a requisição e, se encontrada, deleta a entrada do {{domxref("Cache")}} e retorna uma {{jsxref("Promise")}} que se resolve para <code>true</code>. Se nenhuma entrada do {{domxref("Cache")}} for encontrada, ela é resolvida para <code>false</code>.</dd>
 <dt>{{domxref("Cache.keys", "Cache.keys(request, options)")}}</dt>
 <dd>Retorna uma {{jsxref("Promise")}} que resolve em um array de chaves de {{domxref("Cache")}}.</dd>
</dl>

<h2 id="Exemplos">Exemplos</h2>

<p>Este trecho de código é da <a href="https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/selective-caching/service-worker.js">amostra de cache seletivo</a> (veja <a href="https://googlechrome.github.io/samples/service-worker/selective-caching/">seleção live de cache</a>), ele utiliza {{domxref("CacheStorage.open", "CacheStorage.open(cacheName)")}} para abrir quaisquer objetos {{domxref("Cache")}} com um cabeçalho <code>Content-Type</code> que inicie com <code>font/</code>.</p>

<p>Então, utilizamos {{domxref("Cache.match", "Cache.match(request, options)")}} para verificar se já existe uma fonte encontrada no cache e, se existir, retorna-la. Caso contrário, o código busca a fonte da rede e utiliza {{domxref("Cache.put","Cache.put(request, response)")}} para adiciona-la ao cache.</p>

<p>O código gerencia as exceções disparadas pela operação {{domxref("Globalfetch.fetch","fetch()")}}. Note que uma resposta de erro HTTP (como o 404) não vai ativar uma exceção. Será retornado um objeto de resposta padrão que possui seu próprio código de erros.</p>

<p>O trecho também mostra as melhores práticas de versionamento de caches utilizadas pelo service worker. Mesmo que só estejamos utilizando um cache neste exemplo, a mesma aproximação pode ser utilizada para múltiplos caches. Mapeamos um identificador para um cache específico e versionado. Por fim, o código deleta todos os cache que não estão presentes em <code>CURRENT_CACHES</code>.</p>

<p>No exemplo, "Caches" é um atributo dos service workers no WorkerGlobalScope. Ele contém o CacheStorage, um objeto pelo qual podemos acessar a <a href="https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage">API de mesmo nome</a>.</p>

<div class="note"><strong>Nota:</strong> No Chrome, visite <code>chrome://inspect/#service-workers</code> e clique no link "inspect" abaixo do service worker registrado para analisar os logs das várias ações que o script "<a href="https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/selective-caching/service-worker.js">service-worker.js</a>" está executando.</div>

<pre class="brush: js">var CACHE_VERSION = 1;

// Identificador menor para uma versão específica do cache
var CURRENT_CACHES = {
  font: 'font-cache-v' + CACHE_VERSION
};

self.addEventListener('activate', function(event) {
  var expectedCacheNames = Object.keys(CURRENT_CACHES).map(function(key) {
    return CURRENT_CACHES[key];
  });

  // O worker não vai ser tratado como ativo até que a Promise se resolva.
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (expectedCacheNames.indexOf(cacheName) == -1) {
            console.log('Deletando cache expirado:', cacheName);

            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

self.addEventListener('fetch', function(event) {
  console.log('Obtendo evento fetch para', event.request.url);

  event.respondWith(

    // Abre o objeto de cache que inicia com 'font'
    caches.open(CURRENT_CACHES['font']).then(function(cache) {
      return cache.match(event.request).then(function(response) {
        if (response) {
          console.log(' Encontrou resposta em cache:', response);

          return response;
        }
      }).catch(function(error) {

        // Trata exceções que vem de match() ou fetch().
        console.error('  Erro na handler:', error);

        throw error;
      });
    })
  );
});</pre>

<h2 id="Especificações">Especificações</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Especificação</th>
   <th scope="col">Status</th>
   <th scope="col">Comentário</th>
  </tr>
  <tr>
   <td>{{SpecName('Service Workers', '#cache', 'Cache')}}</td>
   <td>{{Spec2('Service Workers')}}</td>
   <td>Definição inicial</td>
  </tr>
 </tbody>
</table>

<h2 id="Tabela_de_compatibilidade">Tabela de compatibilidade</h2>

<div>{{CompatibilityTable}}</div>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Recurso</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari (WebKit)</th>
  </tr>
  <tr>
   <td>Suporte básico</td>
   <td>{{CompatChrome(40.0)}}</td>
   <td>{{CompatGeckoDesktop(39)}}<sup>[1]</sup></td>
   <td>{{CompatNo}}</td>
   <td>24</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td>add()</td>
   <td>{{CompatChrome(44.0)}}</td>
   <td>{{CompatVersionUnknown}}<sup>[1]</sup></td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
  <tr>
   <td>addAll()</td>
   <td>{{CompatChrome(46.0)}}</td>
   <td>{{CompatVersionUnknown}}<sup>[1]</sup></td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
  <tr>
   <td>matchAll()</td>
   <td>{{CompatChrome(47.0)}}</td>
   <td>{{CompatVersionUnknown}}<sup>[1]</sup></td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
  <tr>
   <td>Requere HTTPS para <code>add()</code>, <code>addAll()</code>, e <code>put()</code></td>
   <td>{{CompatChrome(46.0)}}</td>
   <td>{{CompatVersionUnknown}}<sup>[1]</sup></td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Recurso</th>
   <th>Android</th>
   <th>Android Webview</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>Firefox OS</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
   <th>Chrome for Android</th>
  </tr>
  <tr>
   <td>Suporte básico</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatGeckoMobile(39)}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatChrome(40.0)}}</td>
  </tr>
  <tr>
   <td>add()</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatChrome(44.0)}}</td>
  </tr>
  <tr>
   <td>addAll()</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatChrome(46.0)}}</td>
  </tr>
  <tr>
   <td>matchAll()</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatChrome(46.0)}}</td>
  </tr>
  <tr>
   <td>Requere HTTPS para <code>add()</code>, <code>addAll()</code>, e <code>put()</code></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatChrome(46.0)}}</td>
  </tr>
 </tbody>
</table>
</div>

<p>[1] Service workers (e <a href="/en-US/docs/Web/API/Push_API">Push</a>) foram desabilitados no <a href="https://www.mozilla.org/en-US/firefox/organizations/">Firefox 45 &amp; 52 Extended Support Releases</a> (ESR.)</p>

<h2 id="Ver_também">Ver também</h2>

<ul>
 <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker_API/Using_Service_Workers">Usando Service Workers</a></li>
 <li><a href="https://github.com/mdn/sw-test">Exemplo básico de service workers</a></li>
 <li><a href="https://jakearchibald.github.io/isserviceworkerready/">Service workers estão prontos?</a></li>
 <li>{{jsxref("Promise")}}</li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers">Usando Web Workers</a></li>
</ul>