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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
|
---
title: Cross-Origin Resource Sharing (CORS)
slug: Web/HTTP/CORS
tags:
- AJAX
- CORS
- HTTP
- XMLHttpRequest
translation_of: Web/HTTP/CORS
original_slug: Web/HTTP/Controle_Acesso_CORS
---
<div>{{HTTPSidebar}}</div>
<p>{{Glossary("CORS")}} - Cross-Origin Resource Sharing (Compartilhamento de recursos com origens diferentes) é um mecanismo que usa cabeçalhos adicionais {{Glossary("HTTP")}} para informar a um navegador que permita que um aplicativo Web seja executado em uma origem (domínio) com permissão para acessar recursos selecionados de um servidor em uma origem distinta. Um aplicativo Web executa uma <strong>requisição <em>cross-origin</em> HTTP </strong>ao solicitar um recurso que tenha uma origem diferente (domínio, protocolo e porta) da sua própria origem.</p>
<p>Um exemplo de requisição <em>cross-origin</em>: o código JavaScript <em>frontend </em>de um aplicativo web disponível em <code>http://domain-a.com</code> usa {{domxref ("XMLHttpRequest")}} para fazer uma requisição para <code>http://api.domain-b.com/data.json</code>.</p>
<p>Por motivos de segurança, navegadores restringem requisições <em>cross-origin</em> HTTP iniciadas por scripts. Por exemplo, <code>XMLHttpRequest</code> e <a href="/pt-BR/docs/Web/API/Fetch_API">Fetch API</a> seguem a <a href="/en-US/docs/Web/Security/Same-origin_policy">política de mesma origem</a> (<em>same-origin policy</em>). Isso significa que um aplicativo web que faz uso dessas APIs só poderá fazer solicitações para recursos de mesma origem da qual o aplicativo foi carregado, a menos que a resposta da outra origem inclua os cabeçalhos CORS corretos.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14295/CORS_principle.png" style="height: 305px; width: 440px;"></p>
<p>O mecânismo CORS suporta requisições seguras do tipo <em>cross-origin e </em>transferências de dados entre navegadores e servidores web. Navegadores modernos usam o CORS em uma API contêiner, como <code>XMLHttpRequest</code> ou <a href="/pt-BR/docs/Web/API/Fetch_API">Fetch</a>, para ajudar a reduzir os riscos de requisições <em>cross-origin</em> HTTP.</p>
<h2 id="Quem_deve_ler_este_artigo">Quem deve ler este artigo?</h2>
<p>Todos, realmente.</p>
<p>Este artigo destina-se a administradores da Web, desenvolvedores de servidores e desenvolvedores front-end. Os navegadores modernos lidam com os componentes do lado cliente em compartilhamento entre origens, incluindo cabeçalhos e aplicação de políticas. Mas esse novo padrão significa que os servidores precisam lidar com novos cabeçalhos de requisição e resposta. Outro artigo para desenvolvedores de servidores que discutem <a href="en-US/docs/Web/HTTP/Server-Side_Access_Control">compartilhamento <em>cross-origin</em> a partir de uma perspectiva de servidor (com fragmentos de código PHP)</a>, pode ser uma leitura complementar.</p>
<h2 id="Quais_solicitações_usam_o_CORS">Quais solicitações usam o CORS?</h2>
<p>Esse <a href="https://fetch.spec.whatwg.org/#http-cors-protocol">padrão de compartilhamento <em>cross-origin</em></a> é usado para habilitar solicitações HTTP entre sites para:</p>
<ul>
<li>Chamadas {{domxref("XMLHttpRequest")}} ou <a href="/pt-BR/docs/Web/API/Fetch_API">Fetch API</a> pela comunicação entre origens diferentes, tal como discutido acima.</li>
<li>Web Fonts (para o uso de fontes pelo <em>cross-domain</em> em <code>@font</code> do CSS), <a href="https://www.w3.org/TR/css-fonts-3/#font-fetching-requirements">para que os servidores possam implantar fontes TrueType que só podem ser carregadas em origens diferentes e usadas por sites com autorização para isso</a>.</li>
<li><a href="/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">Texturas WebGL</a>.</li>
<li><em>Frames </em>de Imagens/vídeos desenhados em uma tela usando {{domxref("CanvasRenderingContext2D.drawImage()", "drawImage()")}}.</li>
</ul>
<p>Este artigo é uma discussão geral sobre <em>Cross-Origin Resource Sharing</em> (Compartilhamento de recursos com origens diferentes) e inclui uma discussão de cabeçalhos HTTP necessários.</p>
<h2 id="Visão_Geral">Visão Geral</h2>
<p>O padrão <em>Cross-Origin Resource Sharing</em> trabalha adicionando novos <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers">cabeçalhos HTTP</a> que permitem que os servidores descrevam um conjunto de origens que possuem permissão a ler uma informação usando o navegador. Além disso, para métodos de requisição HTTP que podem causar efeitos colaterais nos dados do servidor (em particular, para métodos HTTP diferentes de {{HTTPMethod("GET")}} ou para uso de {{HTTPMethod("POST")}} com certos <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types">MIME types</a>), a especificação exige que navegadores "pré-enviem" a requisição, solicitando os métodos suportados pelo servidor com um método de requisição HTTP {{HTTPMethod("OPTIONS")}} e, após a "aprovação", o servidor envia a requisição verdadeira com o método de requisição HTTP correto. Servidores também podem notificar clientes se "credenciais" (incluindo <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies">Cookies</a> e dados de autenticação HTTP) devem ser enviadas com as requisições.</p>
<p>Falhas no CORS resultam em erros, mas por questões de segurança, detalhes sobre erros não estão disponíveis no código JavaScript. O código tem apenas conhecimento de que ocorreu um erro. A única maneira para determinar especificamente o que ocorreu de errado é procurar no console do navegador por mais detalhes.</p>
<p>Seções subsequentes discutem cenários, assim como fornecem um detalhamento dos cabeçalhos HTTP utilizados.</p>
<h2 id="Exemplos_de_cenários_com_controle_de_acesso">Exemplos de cenários com controle de acesso</h2>
<p>Aqui, apresentamos três cenários que ilustram como <em>Cross-Origin Resource Sharing</em> funciona. Todos estes exemplos usam o objeto {{domxref("XMLHttpRequest")}}, que pode ser utilizado para fazer requisições entre origens em qualquer navegador compatível.</p>
<p>Os snippets JavaScript inclusos nessas seções (e instâncias executáveis de código do lado servidor que tratam corretamente essas requisições entre origens) podem ser encontrados "em ação" aqui: <a class="external" href="http://arunranga.com/examples/access-control/">http://arunranga.com/examples/access-control/</a>, e irão funcionar em navegadores que suportam <code>XMLHttpRequest</code> entre origens.</p>
<p>Uma discussão sobre <em>Cross-Origin Resource Sharing</em> a partir da perspectiva do servidor (incluindo snippets de código PHP) pode ser encontrada no artigo <a href="/en-US/docs/Web/HTTP/Server-Side_Access_Control">Server-Side Access Control (CORS)</a>.</p>
<h3 id="Requisições_simples">Requisições simples</h3>
<p>Algumas requisições não acionam um <a href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">pré-envio CORS</a>. Essas são denominadas neste artigo como “requisições simples” (<em>simple request</em>), embora a especificação {{SpecName('Fetch')}} (que define CORS) não utilize esse termo. Uma requisição que não aciona um <a href="/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests">pré-envio CORS</a> — denominada “requisição simples” — é uma que <strong>atende todas as seguintes condições</strong>:</p>
<ul>
<li>Os únicos métodos permitidos são:
<ul>
<li>{{HTTPMethod("GET")}}</li>
<li>{{HTTPMethod("HEAD")}}</li>
<li>{{HTTPMethod("POST")}}</li>
</ul>
</li>
<li>Além dos cabeçalhos definidos automaticamente pelo agente do usuário (por exemplo, {{HTTPHeader("Connection")}}, {{HTTPHeader("User-Agent")}} ou <a href="https://fetch.spec.whatwg.org/#forbidden-header-name">qualquer um dos outros cabeçalhos com nomes definidos na especificação Fetch como “<em>forbidden header name</em>”</a>), os únicos cabeçalhos que podem ser definidos manualmente são <a href="https://fetch.spec.whatwg.org/#cors-safelisted-request-header">aqueles cujo a especificação Fetch define como sendo um “<em>CORS-safelisted request-header</em>”</a>, que são:
<ul>
<li>{{HTTPHeader("Accept")}}</li>
<li>{{HTTPHeader("Accept-Language")}}</li>
<li>{{HTTPHeader("Content-Language")}}</li>
<li>{{HTTPHeader("Content-Type")}} (porém observe os requisitos adicionais abaixo)</li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#dpr">DPR</a></code></li>
<li>{{HTTPHeader("Downlink")}}</li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#save-data">Save-Data</a></code></li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#viewport-width">Viewport-Width</a></code></li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#width">Width</a></code></li>
</ul>
</li>
<li>Os únicos valores permitidos para o {{HTTPHeader("Content-Type")}} do cabeçalho são:
<ul>
<li><code>application/x-www-form-urlencoded</code></li>
<li><code>multipart/form-data</code></li>
<li><code>text/plain</code></li>
</ul>
</li>
<li>Nenhum <em>event listener</em> é registrado em qualquer objeto {{domxref("XMLHttpRequestUpload")}} usado na requisição, estes são acessados usando a propriedade {{domxref("XMLHttpRequest.upload")}}.</li>
<li>Nenhum objeto {{domxref("ReadableStream")}} é usado na requisição.</li>
</ul>
<div class="note"><strong>Nota:</strong> Esses são os mesmos tipos de requisições entre origens distintas que o conteúdo da web já pode realizar e nenhum dado dado de resposta é liberado ao solicitante, a menos que o servidor envie um cabeçalho adequado. Portanto, sites que impedem a falsificação de requisições entre origens não tem nada a temer em relação ao controle de acesso HTTP.</div>
<div class="note"><strong>Nota:</strong> O WebKit Nightly e Safari Technology Preview impõem restrições adicionais nos valores permitidos nos cabeçalhos {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}} e {{HTTPHeader("Content-Language")}}. Caso algum destes cabeçalhos tenham valores ”não-padronizados”, o WebKit/Safari não considera que a requisição atenda as condições para uma “requisição simples”. O que o WebKit/Safari considera valores “não-padronizados” para estes cabeçalhos não é documentado exceto nos seguintes bugs do WebKit: <em><a href="https://bugs.webkit.org/show_bug.cgi?id=165178" rel="nofollow noreferrer">Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=165566" rel="nofollow noreferrer">Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS</a></em> e <em><a href="https://bugs.webkit.org/show_bug.cgi?id=166363" rel="nofollow noreferrer">Switch to a blacklist model for restricted Accept headers in simple CORS requests</a></em>. Nenhum outro navegador implementa estas restrições adicionais, pois elas não são parte da especificação.</div>
<p>Por exemplo, suponha que o conteúdo web no domínio <code class="plain">http://foo.example</code> deseje chamar (<code>invocation</code> do exemplo abaixo) um outro conteúdo no domínio <code class="plain">http://bar.other</code>. Esse código Javascript pode estar hospedado em foo.example:</p>
<pre class="brush: js notranslate" id="line1">var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/public-data/';
function callOtherDomain() {
if(invocation) {
invocation.open('GET', url, true);
invocation.onreadystatechange = handler;
invocation.send();
}
}
</pre>
<p>Isso fará uma troca simples entre cliente e servidor, utilizando o cabeçalho CORS para tratar os privilégios.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14293/simple_req.png" style="height: 224px; width: 521px;"></p>
<p>Neste caso, vamos ver o que o navegador enviará ao servidor e vamos olhar como o servidor responde:</p>
<pre class="brush: html notranslate">GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[XML Data]
</pre>
<p>As linhas de 1 a 10 são enviadas no header. Note que o cabeçalho principal da requisição HTTP aqui é {{HTTPHeader("Origin")}} na linha 10, o qual revela que a chamada é proveniente de um conteúdo no domínio <code class="plain">http://foo.example</code>.</p>
<p>As linhas de 13 a 22 mostram a resposta HTTP do servidor no domínio <code class="plain">http://bar.other</code>. Nesta resposta, o servidor envia de volta um cabeçalho {{HTTPHeader("Access-Control-Allow-Origin")}} exibido na linha 16. O uso dos cabeçalhos {{HTTPHeader("Origin")}} e {{HTTPHeader("Access-Control-Allow-Origin")}} mostram o protocolo de controle de acesso em seu uso mais simples. Neste caso, o servidor responde com <code>Access-Control-Allow-Origin: *</code>, o que significa que o recurso pode ser acessado por <strong>qualquer</strong> domínio pela comunicação entre origens. Se os proprietários dos recursos em <code class="plain">http://bar.other</code> desejarem restringir o acesso ao conteúdo para o mesmo ser apenas de <code class="plain">http://foo.example</code>, eles retornaram:</p>
<p><code class="plain">Access-Control-Allow-Origin: http://foo.example</code></p>
<p>Observe que, agora, nenhum dominio além de <code class="plain">http://foo.example</code> (identificado na requisição pelo cabeçalho ORIGIN: como na linha 10) pode acessar o recurso pela comunicação entre origens. O cabeçalho <code>Access-Control-Allow-Origin</code> deve conter o valor que foi enviado no cabeçalho <code>Origin</code> da requisição. </p>
<h3 id="Requisições_com_pré-envio">Requisições com pré-envio</h3>
<p>Ao contrário de <a href="/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests">“requisições simples” (discutido acima)</a>, requisições com "pré-envio" (<em>Preflighted requests</em>) primeiramente enviam uma requisição HTTP através do método {{HTTPMethod("OPTIONS")}} para obter um recurso em outro domínio, a fim de determinar se de fato a requisição atual é segura para envio. Requisições entre sites possuem pré-envio, já que podem interferir em dados do usuário.</p>
<p>Em particular, uma requisição tem um pré-envio <strong>se qualquer das seguintes condições</strong> for verdadeira:</p>
<ul>
<li><strong>Se</strong> a requisição usa algum dos seguintes métodos:
<ul>
<li>{{HTTPMethod("PUT")}}</li>
<li>{{HTTPMethod("DELETE")}}</li>
<li>{{HTTPMethod("CONNECT")}}</li>
<li>{{HTTPMethod("OPTIONS")}}</li>
<li>{{HTTPMethod("TRACE")}}</li>
<li>{{HTTPMethod("PATCH")}}</li>
</ul>
</li>
<li><strong>Ou se</strong>, além dos cabeçalhos definidos automaticamente pelo agente do usuário (por exemplo, {{HTTPHeader("Connection")}}, {HTTPHeader("User-Agent")}} ou <a href="https://fetch.spec.whatwg.org/#forbidden-header-name">qualquer <strong>OUTRO</strong> cabeçalho com um nome definido na especificação Fetch como “<em>forbidden header name</em>”</a>), a requisição inclui quaisquer cabeçalhos <strong>além</strong> <a href="https://fetch.spec.whatwg.org/#cors-safelisted-request-header">daqueles que a especificação Fetch define como sendo um “<em>CORS-safelisted request-header</em>”</a>, que são:
<ul>
<li>{{HTTPHeader("Accept")}}</li>
<li>{{HTTPHeader("Accept-Language")}}</li>
<li>{{HTTPHeader("Content-Language")}}</li>
<li>{{HTTPHeader("Content-Type")}} (porém observe os requisitos adicionais abaixo)</li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#dpr">DPR</a></code></li>
<li>{{HTTPHeader("Downlink")}}</li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#save-data">Save-Data</a></code></li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#viewport-width">Viewport-Width</a></code></li>
<li><code><a href="http://httpwg.org/http-extensions/client-hints.html#width">Width</a></code></li>
</ul>
</li>
<li><strong>Ou se</strong> o {{HTTPHeader("Content-Type")}} do cabeçalho <strong>tem</strong> <strong>outro</strong> valor que:
<ul>
<li><code>application/x-www-form-urlencoded</code></li>
<li><code>multipart/form-data</code></li>
<li><code>text/plain</code></li>
</ul>
</li>
<li><strong>Ou se</strong> um ou mais <em>event listener</em> estiver registrado em um objeto {{domxref ("XMLHttpRequestUpload")}} usado nessa requisição.</li>
<li><strong>Ou se</strong> um objeto {{domxref("ReadableStream")}} é usado nessa requisição.</li>
</ul>
<div class="note"><strong>Nota:</strong> WebKit Nightly e Safari Technology Preview colocam restrições adicionais nos valores permitidos dos cabeçalhos {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}} e {{HTTPHeader("Content-Language")}}. Caso qualquer um desses cabeçalhos tenha algum valor fora do padrão (non-standard), o WebKit/Safari faz o pré-envio da requisição. O que o WebKit/Safari considera como valor “non-standard” para tais cabeçalhos não está documentado, exceto nos seguintes bugs do WebKit: <a href="https://bugs.webkit.org/show_bug.cgi?id=165178" rel="nofollow noreferrer">Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=165566" rel="nofollow noreferrer">Allow commas in Accept, Accept-Language, e Content-Language request headers for simple CORS</a> e <a href="https://bugs.webkit.org/show_bug.cgi?id=166363" rel="nofollow noreferrer">Switch to a blacklist model for restricted Accept headers in simple CORS requests</a>. Nenhum outro navegador implementa estas restrições adicionais, pois elas não são parte da especificação.</div>
<p>O exemplo a seguir é de uma requisição com pré-envio.</p>
<pre class="brush: js notranslate" id="line1">var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
function callOtherDomain(){
if(invocation)
{
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.onreadystatechange = handler;
invocation.send(body);
}
}
......
</pre>
<p>No exemplo acima, a linha 3 cria um XML para enviar com a requisição <code>POST</code> da linha 8. Também, na linha 9, é definido um cabeçalho de uma requisição HTTP "personalizada" (non-standard) com (<code>X-PINGOTHER: pingpong</code>). Tais cabeçalhos não fazem parte do protocolo HTTP/1.1, mas podem ser usados para aplicações web. Já que a requisição usa um Content-Type do tipo <code>application/xml</code> e como é uma requisição personalizada, esta requisição faz um pré-envio.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14289/prelight.png"></p>
<p>(Observação: conforme descrito abaixo, a requisição POST real não inclui os cabeçalhos Access-Control-Request- *; eles são necessários apenas para a requisição OPTIONS.)</p>
<p>Vamos conferir a comunicação completa que ocorre entre cliente e servidor. A primeira comunicação é a <em>requisição com pré-envio/resposta</em>:</p>
<pre class="brush: shell;highlight:[10,11,17,18,19,20] notranslate">OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
</pre>
<p>Uma vez que a requisição com pré-envio é completa, a requisição efetiva será enviada:</p>
<pre class="brush:shell;highlight:[13,23] notranslate">POST /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: http://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: http://foo.example
Pragma: no-cache
Cache-Control: no-cache
<?xml version="1.0"?><person><name>Arun</name></person>
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain
[Some GZIP'd payload]
</pre>
<p>As linhas de 1 a 12 acima representam a requisição com pré-envio tendo o método {{HTTPMethod("OPTIONS")}}. O navegador determina que precisa fazer este envio baseado nos parâmetros da requisição do código JavaScript acima utilizado, para que o servidor possa responder caso seja aceitável o envio da requisição com os dados parâmetros da mesma. OPTIONS é um método HTTP/1.1 usado para determinar informações complementares dos servidores, sendo o mesmo um método {{Glossary("safe")}}, o que significa que não pode ser utilizado para troca de recurso. Note que junto da requisição OPTIONS, outros dois cabeçalhos são enviados (linhas 10 e 11, respectivamente):</p>
<pre class="notranslate">Access-Control-Request-Method: POST
Access-Controa l-Request-Headers: X-PINGOTHER, Content-Type
</pre>
<p>O cabeçalho {{HTTPHeader("Access-Control-Request-Method")}} notifica o servidor como sendo uma parte da requisição com pré-envio que, quando a requisição efetiva é enviada, será enviada com uma requisição de método <code>POST</code>. O cabeçalho {{HTTPHeader("Access-Control-Request-Headers")}} notifica o servidor que quando a requisição efetiva fora enviada, será enviada com os seguintes cabeçalhos personalizados <code>X-PINGOTHER</code> e <code>Content-Type</code>. O servidor agora tem a oportunidade para definir se deseja aceitar uma requisição sob estas condições.</p>
<p>As linhas 14 a 26 acima são as respostas que o servidor devolve, indicando que o método (<code>POST</code>) e os cabeçalhos (<code>X-PINGOTHER</code>) da requisição são aceitáveis. Em particular, vejamos as linhas 17 a 20:</p>
<pre class="notranslate">Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400</pre>
<p>O servidor responde com <code>Access-Control-Allow-Methods</code> e diz que <code>POST</code>, <code>GET</code>, e <code>OPTIONS</code> são métodos viáveis para requerir o recurso em questão. Perceba que este cabeçalho é similar ao cabeçalho da resposta {{HTTPHeader("Allow")}}, mas usado estritamente dentro do contexto do controle de acesso.</p>
<p>O servidor envia também <code>Access-Control-Allow-Headers</code> com um valor de "<code>X-PINGOTHER, Content-Type</code>", confirmando estes são cabeçalhos permitidos a serem usados com a requisição efetiva. Assim como <code>Access-Control-Allow-Methods</code>, <code>Access-Control-Allow-Headers</code> é uma lista de cabeçalhos aceitáveis, separados por vírgula.</p>
<p>Por fim, {{HTTPHeader("Access-Control-Max-Age")}} traz o valor em segundos de quão longo pode ser mantida em cache a resposta da requisição pré-envio sem o envio de outra requisição pré-envio. Neste caso, 86400 segundos são 24 horas. Note que cada browser tem um<a href="/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age"> valor interno máximo</a> que toma precedência quado <code>Access-Control-Max-Age</code> for maior.</p>
<h4 id="Requisições_com_pré-envio_e_redirecionamento">Requisições com pré-envio e redirecionamento</h4>
<p>Not all browsers currently support following redirects after a preflighted request. If a redirect occurs after a preflighted request, some browsers currently will report an error message such as the following.</p>
<blockquote>
<p>The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight</p>
</blockquote>
<blockquote>
<p>Request requires preflight, which is disallowed to follow cross-origin redirect</p>
</blockquote>
<p>The CORS protocol originally required that behavior but <a href="https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2">was subsequently changed to no longer require it</a>. However, not all browsers have implemented the change, and so still exhibit the behavior that was originally required.</p>
<p>So until all browsers catch up with the spec, you may be able to work around this limitation by doing one or both of the following:</p>
<ul>
<li>change the server-side behavior to avoid the preflight and/or to avoid the redirect—if you have control over the server the request is being made to</li>
<li>change the request such that it is a <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Controle_Acesso_CORS$edit#Simple_requests">simple request</a> that doesn’t cause a preflight</li>
</ul>
<p>But if it’s not possible to make those changes, then another way that may be possible is to this:</p>
<ol>
<li>Make a <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Controle_Acesso_CORS$edit#Simple_requests">simple request</a> (using {{domxref("Response.url")}} for the Fetch API, or {{domxref("XMLHttpRequest.responseURL")}}) to determine what URL the real preflighted request would end up at.</li>
<li>Make another request (the “real” request) using the URL you obtained from <code>Response.url</code> or <code>XMLHttpRequest.responseURL</code> in the first step.</li>
</ol>
<p>However, if the request is one that triggers a preflight due to the presence of the <code>Authorization</code> header in the request, you won’t be able to work around the limitation using the steps above. And you won’t be able to work around it at all unless you have control over the server the request is being made to.</p>
<h3 id="Requisições_com_credenciais">Requisições com credenciais</h3>
<p>The most interesting capability exposed by both {{domxref("XMLHttpRequest")}} or <a href="/en-US/docs/Web/API/Fetch_API">Fetch</a> and CORS is the ability to make "credentialed" requests that are aware of <a href="/en-US/docs/Web/HTTP/Cookies">HTTP cookies</a> and HTTP Authentication information. By default, in cross-site {{domxref("XMLHttpRequest")}} or <a href="/en-US/docs/Web/API/Fetch_API">Fetch</a> invocations, browsers will <strong>not</strong> send credentials. A specific flag has to be set on the {{domxref("XMLHttpRequest")}} object or the {{domxref("Request")}} constructor when it is invoked.</p>
<p>In this example, content originally loaded from <code class="plain">http://foo.example</code> makes a simple GET request to a resource on <code class="plain">http://bar.other</code> which sets Cookies. Content on foo.example might contain JavaScript like this:</p>
<pre class="brush: js notranslate" id="line1">var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;
invocation.onreadystatechange = handler;
invocation.send();
}
}</pre>
<p>Line 7 shows the flag on {{domxref("XMLHttpRequest")}} that has to be set in order to make the invocation with Cookies, namely the <code>withCredentials</code> boolean value. By default, the invocation is made without Cookies. Since this is a simple <code>GET</code> request, it is not preflighted, but the browser will <strong>reject</strong> any response that does not have the {{HTTPHeader("Access-Control-Allow-Credentials")}}: <code>true</code> header, and <strong>not</strong> make the response available to the invoking web content.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/14291/cred-req.png" style="height: 223px; width: 521px;"></p>
<p>Here is a sample exchange between client and server:</p>
<pre class="brush: shell notranslate">GET /resources/access-control-with-credentials/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/credential.html
Origin: http://foo.example
Cookie: pageAccess=2
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-Powered-By: PHP/5.2.6
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
[text/plain payload]
</pre>
<p>Although line 11 contains the Cookie destined for the content on <code class="plain">http://bar.other</code>, if bar.other did not respond with an {{HTTPHeader("Access-Control-Allow-Credentials")}}<code>: true</code> (line 19) the response would be ignored and not made available to web content.</p>
<h4 id="Solicitações_credenciadas_e_curingas_wildcards">Solicitações credenciadas e curingas (<em>wildcards</em>)</h4>
<p>When responding to a credentialed request, the server <strong>must</strong> specify an origin in the value of the <code>Access-Control-Allow-Origin</code> header, instead of specifying the "<code>*</code>" wildcard.</p>
<p>Because the request headers in the above example include a <code>Cookie</code> header, the request would fail if the value of the <code>Access-Control-Allow-Origin</code> header were "*". But it does not fail: Because the value of the <code>Access-Control-Allow-Origin</code> header is "<code class="plain">http://foo.example</code>" (an actual origin) rather than the "<code>*</code>" wildcard, the credential-cognizant content is returned to the invoking web content.</p>
<p>Note that the <code>Set-Cookie</code> response header in the example above also sets a further cookie. In case of failure, an exception—depending on the API used—is raised.</p>
<p>All of these examples can be <a class="external" href="http://arunranga.com/examples/access-control/">seen working here</a>. The next section deals with the actual HTTP headers.</p>
<h2 id="Os_cabeçalhos_de_resposta_HTTP">Os cabeçalhos de resposta HTTP</h2>
<p>This section lists the HTTP response headers that servers send back for access control requests as defined by the Cross-Origin Resource Sharing specification. The previous section gives an overview of these in action.</p>
<h3 id="Access-Control-Allow-Origin">Access-Control-Allow-Origin</h3>
<p>A returned resource may have one {{HTTPHeader("Access-Control-Allow-Origin")}} header, with the following syntax:</p>
<pre class="notranslate">Access-Control-Allow-Origin: <origin> | *
</pre>
<p>The <code>origin</code> parameter specifies a URI that may access the resource. The browser must enforce this. For requests <strong>without</strong> credentials, the server may specify "*" as a wildcard, thereby allowing any origin to access the resource.</p>
<p>For example, to allow http://mozilla.org to access the resource, you can specify:</p>
<pre class="notranslate">Access-Control-Allow-Origin: http://mozilla.org</pre>
<p>If the server specifies an origin host rather than "*", then it could also include Origin in the Vary response header to indicate to clients that server responses will differ based on the value of the Origin request header.</p>
<h3 id="Access-Control-Expose-Headers">Access-Control-Expose-Headers</h3>
<p>The {{HTTPHeader("Access-Control-Expose-Headers")}} header lets a server whitelist headers that browsers are allowed to access. For example:</p>
<pre class="notranslate">Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
</pre>
<p>This allows the <code>X-My-Custom-Header</code> and <code>X-Another-Custom-Header</code> headers to be exposed to the browser.</p>
<h3 id="Access-Control-Max-Age">Access-Control-Max-Age</h3>
<p>The {{HTTPHeader("Access-Control-Max-Age")}} header indicates how long the results of a preflight request can be cached. For an example of a preflight request, see the above examples.</p>
<pre class="notranslate">Access-Control-Max-Age: <delta-seconds>
</pre>
<p>The <code>delta-seconds</code> parameter indicates the number of seconds the results can be cached.</p>
<h3 id="Access-Control-Allow-Credentials">Access-Control-Allow-Credentials</h3>
<p>The {{HTTPHeader("Access-Control-Allow-Credentials")}} header Indicates whether or not the response to the request can be exposed when the <code>credentials</code> flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note that simple <code>GET</code> requests are not preflighted, and so if a request is made for a resource with credentials, if this header is not returned with the resource, the response is ignored by the browser and not returned to web content.</p>
<pre class="notranslate">Access-Control-Allow-Credentials: true
</pre>
<p><a class="internal" href="#Requisições_com_credenciais">Credentialed requests</a> are discussed above.</p>
<h3 id="Access-Control-Allow-Methods">Access-Control-Allow-Methods</h3>
<p>O {{HTTPHeader("Access-Control-Allow-Methods")}} cabeçalho especifica o método ou os métodos permitidos ao acessar o recurso. Isso é usado em resposta há uma requisição preflight. As condições na qual a requisição é preflight são discutidas à seguir.</p>
<pre class="notranslate">Access-Control-Allow-Methods: <method>[, <method>]*
</pre>
<p>An example of a <a class="internal" href="#Preflighted_requests">preflight request is given above</a>, including an example which sends this header to the browser.</p>
<h3 id="Access-Control-Allow-Headers">Access-Control-Allow-Headers</h3>
<p>The {{HTTPHeader("Access-Control-Allow-Headers")}} header is used in response to a <a class="internal" href="#Preflighted_requests">preflight request</a> to indicate which HTTP headers can be used when making the actual request.</p>
<pre class="notranslate">Access-Control-Allow-Headers: <field-name>[, <field-name>]*
</pre>
<h2 id="Os_cabeçalhos_de_solicitação_HTTP">Os cabeçalhos de solicitação HTTP</h2>
<p>This section lists headers that clients may use when issuing HTTP requests in order to make use of the cross-origin sharing feature. Note that these headers are set for you when making invocations to servers. Developers using cross-site {{domxref("XMLHttpRequest")}} capability do not have to set any cross-origin sharing request headers programmatically.</p>
<h3 id="Origin">Origin</h3>
<p>The {{HTTPHeader("Origin")}} header indicates the origin of the cross-site access request or preflight request.</p>
<pre class="notranslate">Origin: <origin>
</pre>
<p>The origin is a URI indicating the server from which the request initiated. It does not include any path information, but only the server name.</p>
<div class="note"><strong>Note:</strong> The <code>origin</code> can be the empty string; this is useful, for example, if the source is a <code>data</code> URL.</div>
<p>Note that in any access control request, the {{HTTPHeader("Origin")}} header is <strong>always</strong> sent.</p>
<h3 id="Access-Control-Request-Method">Access-Control-Request-Method</h3>
<p>The {{HTTPHeader("Access-Control-Request-Method")}} is used when issuing a preflight request to let the server know what HTTP method will be used when the actual request is made.</p>
<pre class="notranslate">Access-Control-Request-Method: <method>
</pre>
<p>Examples of this usage can be <a class="internal" href="#Preflighted_requests">found above.</a></p>
<h3 id="Access-Control-Request-Headers">Access-Control-Request-Headers</h3>
<p>The {{HTTPHeader("Access-Control-Request-Headers")}} header is used when issuing a preflight request to let the server know what HTTP headers will be used when the actual request is made.</p>
<pre class="notranslate">Access-Control-Request-Headers: <field-name>[, <field-name>]*
</pre>
<p>Examples of this usage can be <a class="internal" href="#Preflighted_requests">found above</a>.</p>
<h2 id="Especificações">Especificações</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('Fetch', '#cors-protocol', 'CORS')}}</td>
<td>{{Spec2('Fetch')}}</td>
<td>New definition; supplants <a href="https://www.w3.org/TR/cors/">W3C CORS</a> specification.</td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidade_entre_Navegadores">Compatibilidade entre Navegadores</h2>
<div class="hidden">
<p>The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
</div>
<p>{{Compat("http.headers.Access-Control-Allow-Origin")}}</p>
<h3 id="Notas_de_compatibilidade">Notas de compatibilidade</h3>
<ul>
<li>Internet Explorer 8 and 9 expose CORS via the <code>XDomainRequest</code> object, but have a full implementation in IE 10. </li>
<li>While Firefox 3.5 introduced support for cross-site XMLHttpRequests and Web Fonts, certain requests were limited until later versions. Specifically, Firefox 7 introduced the ability for cross-site HTTP requests for WebGL Textures, and Firefox 9 added support for Images drawn on a canvas using <code>drawImage</code>.</li>
</ul>
<h2 id="Veja_também">Veja também</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors">CORS errors</a></li>
<li><a href="https://enable-cors.org/server.html">Enable CORS: I want to add CORS support to my server</a></li>
<li>{{domxref("XMLHttpRequest")}}</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a></li>
<li><a href="http://www.kendoui.com/blogs/teamblog/posts/11-10-03/using_cors_with_all_modern_browsers.aspx">Using CORS with All (Modern) Browsers</a></li>
<li><a href="http://www.html5rocks.com/en/tutorials/cors/">Using CORS - HTML5 Rocks</a></li>
<li><a href="https://arunranga.com/examples/access-control/">Code Samples Showing <code>XMLHttpRequest</code> and Cross-Origin Resource Sharing</a></li>
<li><a href="https://github.com/jackblackevo/cors-jsonp-sample">Client-Side & Server-Side (Java) sample for Cross-Origin Resource Sharing (CORS)</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control">Cross-Origin Resource Sharing From a Server-Side Perspective (PHP, etc.)</a></li>
<li><a href="https://stackoverflow.com/questions/43871637/no-access-control-allow-origin-header-is-present-on-the-requested-resource-whe/43881141#43881141">Stack Overflow answer with “how to” info for dealing with common problems</a>:
<ul>
<li>How to avoid the CORS preflight</li>
<li>How to use a CORS proxy to get around <em>“No Access-Control-Allow-Origin header”</em></li>
<li>How to fix <em>“Access-Control-Allow-Origin header must not be the wildcard”</em></li>
</ul>
</li>
</ul>
|