aboutsummaryrefslogtreecommitdiff
path: root/files/it/web/http/cors/index.html
blob: dbf2293abc5c17ea704f9dd5ef23c4a4fe47c6ed (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
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
555
556
557
558
559
560
561
562
563
564
565
---
title: Cross-Origin Resource Sharing (CORS)
slug: Web/HTTP/CORS
tags:
  - AJAX
  - CORS
  - Controllo accessi HTTP
  - Cross-Origin Resource Sharing
  - Fetch
  - Fetch API
  - HTTP
  - Same-origin policy
  - Security
  - Sicurezza
  - XMLHttpRequest
translation_of: Web/HTTP/CORS
---
<p><span class="seoSummary">Il Cross-Origin Resource Sharing ({{Glossary("CORS")}}) è un meccanismo che usa header {{Glossary("HTTP")}} addizionali per indicare a un browser che un'applicazione Web in esecuzione su un'origine (dominio) dispone dell'autorizzazione per accedere alle risorse selezionate da un server di origine diversa.</span> Un'applicazione web invia una <strong>cross-origin HTTP request</strong> quando richiede una risorsa che ha un'origine (protocollo, dominio e porta) differente dalla propria.</p>

<p>Esempio di cross-origin request: Il codice Javascript di  frontend per un'applicazione web servita da <code>http://domain-a.com</code> utilizza {{domxref("XMLHttpRequest")}} per inviare una richiesta a <code>http://api.domain-b.com/data.json</code>.</p>

<p>Per ragioni di sicurezza, i browser limitano le cross-origin HTTP requests che vengono generate all'interno degli scripts. Ad esempio, <code>XMLHttpRequest</code> e la <a href="/en-US/docs/Web/API/Fetch_API">Fetch API</a> seguono la <a href="/en-US/docs/Web/Security/Same-origin_policy">same-origin policy</a>. Ciò significa che un'applicazione web che utilizza queste API può solamente richiedere risorse HTTP dalla stessa origine di caricamento dell'applicazione, a meno che la risposta dall'altra origine includa i corretti header CORS.</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/14295/CORS_principle.png" style="height: 305px; width: 440px;"></p>

<p>Il meccanismo CORS supporta richieste e trasferimenti dati sicuri fra browsers e web servers. I browser moderni usano CORS in container API come <code>XMLHttpRequest</code> o <a href="/en-US/docs/Web/API/Fetch_API">Fetch</a> per aiutare a mitigare i rischi di richieste HTTP cross-origin.</p>

<h2 id="Chi_dovrebbe_leggere_questo_articolo">Chi dovrebbe leggere questo articolo?</h2>

<p>Tutti, davvero.</p>

<p>Più specificamente, questo articolo è per amministratori web, sviluppatori server side e front end. I browser moderni gestiscono i componenti client della cross-origin sharing, inclusi gli headers e applicazione delle policy. Ma questo nuovo standard richiede che i server gestiscano nuovi headers di richiesta e risposta. Un altro articolo per sviluppator server side che discute la <a href="/en-US/docs/Web/HTTP/Server-Side_Access_Control">cross-origin sharing da una prospettiva server (con esempi di codice PHP )</a> è una lettura supplementare.</p>

<h2 id="Quali_tipi_di_richieste_usano_CORS">Quali tipi di richieste usano CORS?</h2>

<p>Questo <a class="external" href="https://fetch.spec.whatwg.org/#http-cors-protocol">cross-origin sharing standard</a> è usato per abilitare richieste HTTP cross-site per:</p>

<ul>
 <li>Invocazioni delle API {{domxref("XMLHttpRequest")}}<a href="/en-US/docs/Web/API/Fetch_API">Fetch</a> in modalità cross-site, come illustrato sopra.</li>
 <li>Web Fonts (per utilizzo cross-domain in <code>@font-face</code> all'interno di regole CSS), <a class="external" href="https://www.w3.org/TR/css-fonts-3/#font-fetching-requirements">così che i server possano esporre fonts TrueType che possano essere caricati ed usati in modalità cross-site solo da siti web a cui è stata concessa l'autorizzazione per farlo.</a></li>
 <li><a href="/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">Texture WebGL</a>.</li>
 <li>Immagini/frame video disegnati su un canvas utilizzando {{domxref("CanvasRenderingContext2D.drawImage()", "drawImage()")}}.</li>
 <li>Fogli di stile (per accesso <a href="/en-US/docs/Web/CSS/CSSOM_View">CSSOM</a>).</li>
 <li>Script (per eccezioni non silenziate).</li>
</ul>

<p>Questo articolo è una discussione generale sul Cross-Origin Resource Sharing e include una trattazione degli header HTTP necessari.</p>

<h2 id="Panoramica_funzionale">Panoramica funzionale</h2>

<p>Lo standard Cross-Origin Resource Sharing funziona aggiungendo nuovi <a href="/en-US/docs/Web/HTTP/Headers">header HTTP</a> che consentono ai server di descrivere l'insieme di origini che sono autorizzate a leggere quelle informazioni tramite un web browser. In aggiunta, per i metodi di richiesta HTTP che possono causare effetti collaterali sui dati del server (in particolare, per i metodi HTTP diversi da {{HTTPMethod("GET")}}, o per l'utilizzo di {{HTTPMethod("POST")}} con determinati <a href="/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types">MIME types</a>), la specifica prevede che il browser "anticipi" la richiesta (questa operazione è detta "preflight"), richiedendo al server i metodi supportati tramite una richiesta HTTP {{HTTPMethod("OPTIONS")}}, e poi, dopo una "approvazione" del server, invii la richiesta effettiva con il metodo HTTP effettivo. I server possono anche informare i client se delle "credenziali" (inclusi <a href="/en-US/docs/Web/HTTP/Cookies">Cookies</a> e dati di autenticazione HTTP) debbano essere inviate insieme alle richieste.</p>

<p>Gli insuccessi CORS generano degli errori, ma per ragioni di sicurezza, i dettagli riguardo a cosa sia andato male <em>non sono disponibili al codice JavaScript</em>. Tutto ciò che il codice può sapere è che si è verificato un errore. L'unico modo per determinare cosa sia andato male nello specifico è guardare la console del browser per i dettagli.</p>

<p>Le sezioni successive discutono alcuni scenari, e provvedono un'analisi dettagliata degli header HTTP usati.</p>

<h2 id="Esempi_di_scenari_di_controllo_accessi">Esempi di scenari di controllo accessi</h2>

<p>Qui presentiamo tre scenari che illustrano come funziona la Cross-Origin Resource Sharing. Tutti questi esempi utilizzano l'oggetto {{domxref("XMLHttpRequest")}}, che può essere usato per creare chiamate cross-site in qualsiasi browser che le supporti.</p>

<p>Gli spezzoni di codice JavaScript inclusi in queste sezioni (e istanze attive di codice server che gestiscono correttamente queste richieste cross-site) possono essere viste in azione su <a class="external" href="http://arunranga.com/examples/access-control/">http://arunranga.com/examples/access-control/</a>, e funzioneranno nei browser che supportano <code>XMLHttpRequest</code> cross-site.</p>

<p>Una trattazione della Cross-Origin Resource Sharing da una prospettiva server (inclusi spezzoni di codice PHP) si possono trovare nell'articolo <a class="internal" href="/en-US/docs/Web/HTTP/Server-Side_Access_Control">Server-Side Access Control (CORS)</a>.</p>

<h3 id="Richieste_semplici">Richieste semplici</h3>

<p>Alcune richieste non scatenano una <a href="#Preflighted_requests">CORS preflight</a>. Queste sono chiamate “richieste semplici” in questo articolo, anche se la specifica {{SpecName('Fetch')}} (che definisce CORS) non utilizza quel termine. Una richiesta che non scatena una <a href="#Preflighted_requests">CORS preflight</a>—una cosiddetta “richiesta semplice”—è una richiesta che soddisfa tutte le seguenti condizioni:</p>

<ul>
 <li>Gli unici metodi permessi sono:
  <ul>
   <li>{{HTTPMethod("GET")}}</li>
   <li>{{HTTPMethod("HEAD")}}</li>
   <li>{{HTTPMethod("POST")}}</li>
  </ul>
 </li>
 <li>A parte gli header impostati automaticamente dallo user agent (ad esempio, {{HTTPHeader("Connection")}}, {{HTTPHeader("User-Agent")}}, o <a href="https://fetch.spec.whatwg.org/#forbidden-header-name">uno qualsiasi degli altri header i cui nomi sono definiti nella specifica Fetch come “forbidden header name”</a>), gli unici header che è consentito impostare manualmente sono <a href="https://fetch.spec.whatwg.org/#cors-safelisted-request-header">quelli che la specifica Fetch definisce come “CORS-safelisted request-header”</a>, che sono:
  <ul>
   <li>{{HTTPHeader("Accept")}}</li>
   <li>{{HTTPHeader("Accept-Language")}}</li>
   <li>{{HTTPHeader("Content-Language")}}</li>
   <li>{{HTTPHeader("Content-Type")}} (tenendo presente i requisiti addizionali sotto)</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>Gli unici valori consentiti per l'header {{HTTPHeader("Content-Type")}} sono:
  <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>Nessun event listener è configurato su alcun oggetto {{domxref("XMLHttpRequestUpload")}} usato nella richiesta; ad essi si accede tramite la proprietà {{domxref("XMLHttpRequest.upload")}} property.</li>
 <li>Nessun oggetto {{domxref("ReadableStream")}} object è usato nella richiesta.</li>
</ul>

<div class="note"><strong>Nota:</strong>  Queste sono lo stesso tipo di richieste cross-site che il web content può già rilasciare, e nessuna informazione è rilasciata al richiedente a meno che il server mandi un header appropriato. Quindi, siti che impediscono la falsificazione di cross-site request non hanno nulla di nuovo da temere dall controllo di accesso HTTP.</div>

<div class="note"><strong>Nota:</strong> WebKit Nightly e Safari Technology Preview pongono restrizioni addizionali sui valori ammessi negli headers {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, e {{HTTPHeader("Content-Language")}}. Se anche solo uno di questi headers hanno valori non-standard, per WebKit/Safari la richiesta non rispetta le condizioni di una "richiesta semplice." Quello che WebKit/Safari considera valori “non-standard” per questi headers non è documentato eccetto nei seguenti bug di 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, and 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>. Nessun altro browser implementa queste restrizioni addizionali, perché queste restrizioni non fanno parte della specifica.</div>

<p>Per esempio, supponiamo che una pagina web su dominio <code class="plain">http://foo.example</code> tenti di accedere a contenuto su dominio <code class="plain">http://bar.other</code>. In Javascript, verrebbe scritto un codice simile al seguente in foo.example:</p>

<pre class="brush: js" 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>Tutto ciò porterà ad un semplice scambio di informazioni tra client e server, usando headers CORS per manipolare i privilegi:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/14293/simple_req.png" style="height: 224px; width: 521px;"></p>

<p>Vediamo cosa il browser manderà al server in questo caso, e come risponderà il server:</p>

<pre class="brush: shell;highlight:[10,16]">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

[Dati XML]
</pre>

<p>Le linee 1 - 10 sono gli header mandati. L'header più importante qui è {{HTTPHeader("Origin")}} alla linea 10, che mostra che l'invocazione origina dal dominio <code class="plain">http://foo.example</code>.</p>

<p>Le linee 13 - 22 mostrano la risposta HTTP dal server al dominio <code class="plain">http://bar.other</code>. In risposta, il server manda un header {{HTTPHeader("Access-Control-Allow-Origin")}} mostrato nella linea 16. L'uso dell'header {{HTTPHeader("Origin")}} e {{HTTPHeader("Access-Control-Allow-Origin")}} dimostrano il protocollo di controllo accesso nella sua forma più semplice. In questo caso, il server risponde con <code>Access-Control-Allow-Origin: *</code> il che significa che la risorsa può essere acceduta da <strong>qualsiasi</strong> dominio. Se i proprietary della risorsa su <code class="plain">http://bar.other</code> vogliono restringere accesso alla risorsa alle sole richieste provenienti da <code class="plain">http://foo.example</code>, risponderebbero con:</p>

<p><code class="plain">Access-Control-Allow-Origin: http://foo.example</code></p>

<p>Nota che ora, nessun dominio a parte <code class="plain">http://foo.example</code> (identificato dall'header ORIGIN: nella richiesta, come nella linea 10) può accedere alla risorsa in maniera cross-site. L'header <code>Access-Control-Allow-Origin</code> deve contenere il valore che è stato mandato nell'header <code>Origin</code> della richiesta.</p>

<h3 id="Richieste_in_preflight">Richieste in preflight</h3>

<p>Al contrario delle "richieste semplici" discusse sopra, le richieste "in preflight" (anticipate) mandano prima una richiesta HTTP tramite il metodo {{HTTPMethod("OPTIONS")}} alla risorsa nell'altro dominio, per determinare se la richiesta vera e propria è sicura. Richieste cross-site vengono anticipate in questo modo perché potrebbero avere implicazioni per la sicurezza dei dati utenti.</p>

<p>In particolare, una richiesta è anticipate se <strong>anche solo una delle seguenti condizioni</strong> è vera:</p>

<ul>
 <li><strong>Se</strong> la richiesta usa uno dei metodo seguenti:

  <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>Oppure se</strong>, a parte gli header impostati automaticamente dall'user agent (ad esempio {{HTTPHeader("Connection")}}, {{HTTPHeader("User-Agent")}}, o <a href="https://fetch.spec.whatwg.org/#forbidden-header-name">un qualunque header con un nome definito nella specifica Fetch come "nome header vietato"</a>), la richiesta include header diversi da <a href="https://fetch.spec.whatwg.org/#cors-safelisted-request-header">quelli che la specifica Fetch definisce "CORS-safelisted request-header"</a>, ossia i seguenti:
  <ul>
   <li>{{HTTPHeader("Accept")}}</li>
   <li>{{HTTPHeader("Accept-Language")}}</li>
   <li>{{HTTPHeader("Content-Language")}}</li>
   <li>{{HTTPHeader("Content-Type")}} (ma nota le restrizioni addizionali specificate sotto)</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>O se</strong> l'header {{HTTPHeader("Content-Type")}} ha un valore diverso dai seguenti:
  <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>O se</strong> uno o più event listeners sono registrati su un oggetto {{domxref("XMLHttpRequestUpload")}} usato nella richiesta.</li>
 <li><strong>O se</strong> un oggetto {{domxref("ReadableStream")}} è usato nella richiesta.</li>
</ul>

<div class="note"><strong>Note:</strong> WebKit Nightly e Safari Technology Preview pongono ulteriori restrizioni sul valori ammessi negli header {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, e {{HTTPHeader("Content-Language")}}. Se anche solo uno di questi headers ha un valore non-standard, WebKit/Safari effettua la richiesta in preflight. Quello che WebKit/Safari considerano valori “non-standard” non è documentato eccetto nei seguenti bug di 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, and 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>. Nessun altro browser implementa questa restrizioni aggiuntive, perché non sono parte della specifica.</div>

<p>Il seguente è un esempio di una richiesta che verrà effettuata in preflight.</p>

<pre class="brush: js" id="line1">var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '&lt;?xml version="1.0"?&gt;&lt;person&gt;&lt;name&gt;Arun&lt;/name&gt;&lt;/person&gt;';

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>Nell'esempio sopra, la linea 3 crea un corpo XML che viene mandato con una richiesta <code>POST</code> alla linea 8. Nella linea 9 viene specificato un header "non-standard" (<code>X-PINGOTHER: pingpong</code>). Questi headers non fanno parte del protocollo HTTP/1.1, ma sono utili per applicazioni web. La richiesta è eseguita in preflight perché usa un Content-Type di <code>application/xml</code> e la richiesta usa un header non-standard.</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/14289/prelight.png"></p>

<p>(Nota: come descritto sopra, la richiesta POST non include gli header Access-Control-Request-*; questi sono necessari solo per le richieste OPTIONS.)</p>

<p>Diamo un'occhiata allo scambio complete tra client e server. Il primo scambio è la richiesta e risposta in preflight:</p>

<pre class="brush: none;highlight:[1,10,11,17-20]">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
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>Quando la richiesta in preflight è completa, la richiesta vera e propria viene mandata:</p>

<pre class="brush: none;">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

&lt;?xml version="1.0"?&gt;&lt;person&gt;&lt;name&gt;Arun&lt;/name&gt;&lt;/person&gt;


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

[Payload compresso con GZIP]
</pre>

<p>Le linee 1 - 12 sopra rappresentano le richieste in preflight con il metodo {{HTTPMethod("OPTIONS")}}. Il browser determina che deve mandare questo in base ai parametri della prima richiesta. OPTIONS è un metodo HTTP/1.1 usato per ricevere informazioni aggiuntive dal server ed è un metodo "safe" (non può cambiare la risorsa). Oltre alla richiesta OPTIONS vengono mandate altre due richieste (linee 10 e 11):</p>

<pre class="brush: none">Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
</pre>

<p>L'header {{HTTPHeader("Access-Control-Request-Method")}} notifica il server che la richiesta vera e propria verrà mandata con un metodo <code>POST</code>. L'header {{HTTPHeader("Access-Control-Request-Headers")}} dice al server che verrà mandata con gli header personalizzati <code>X-PINGOTHER</code> e Content-Type. Ora il server può determinare se vuole accettare una richiesta in queste circostanze.</p>

<p>Le linee 14-26 sono la risposta e indicano che il metodo richiesta (<code>POST</code>) e gli headers (<code>X-PINGOTHER</code>) sono accettabili. In particolare, vediamo le linee 17-20:</p>

<pre class="brush: none">Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400</pre>

<p>Il server risponde con <code>Access-Control-Allow-Methods</code> e dice che <code>POST</code> e <code>GET</code> possono essere usati per accedere alla risorsa. Questo header è simile a {{HTTPHeader("Allow")}} ma è usato solo nel contesto del controllo d'accesso.</p>

<p>The server also sends <code>Access-Control-Allow-Headers</code> with a value of "<code>X-PINGOTHER, Content-Type</code>", confirming that these are permitted headers to be used with the actual request. Like <code>Access-Control-Allow-Methods</code>, <code>Access-Control-Allow-Headers</code> is a comma separated list of acceptable headers.</p>

<p>Finally, {{HTTPHeader("Access-Control-Max-Age")}} gives the value in seconds for how long the response to the preflight request can be cached for without sending another preflight request. In this case, 86400 seconds is 24 hours. Note that each browser has a <a href="/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age">maximum internal value</a> that takes precedence when the <code>Access-Control-Max-Age</code> is greater.</p>

<h4 id="Preflighted_requests_and_redirects">Preflighted requests and redirects</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="#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="#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="Requests_with_credentials">Requests with credentials</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 <code>XMLHttpRequest"</code> 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 <code>XMLHttpRequest"</code> 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" 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: none">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="Credentialed_requests_and_wildcards">Credentialed requests and wildcards</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>

<h4 id="Third-party_cookies">Third-party cookies</h4>

<p>Note that cookies set in CORS responses are subject to normal third-party cookie policies. In the example above, the page is loaded from <code>foo.example</code>, but the cookie on line 22 is sent by <code>bar.other</code>, and would thus not be saved if the user has configured their browser to reject all third-party cookies.</p>

<h2 id="The_HTTP_response_headers">The HTTP response headers</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="brush: none">Access-Control-Allow-Origin: &lt;origin&gt; | *
</pre>

<p><code>Access-Control-Allow-Origin</code> specifies either a single origin, which tells browsers to allow that origin to access the resource; or else — for requests <strong>without</strong> credentials — the "<code>*</code>" wildcard, to tell browsers to allow any origin to access the resource.</p>

<p>For example, to allow code from the origin <code>http://mozilla.org</code> to access the resource, you can specify:</p>

<pre class="brush: none">Access-Control-Allow-Origin: http://mozilla.org</pre>

<p>If the server specifies a single origin rather than the "<code>*</code>" wildcard, then the server should also include <code>Origin</code> in the {{HTTPHeader("Vary")}} response header — to indicate to clients that server responses will differ based on the value of the {{HTTPHeader("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="brush: none">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="brush: none">Access-Control-Max-Age: &lt;delta-seconds&gt;
</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="brush: none">Access-Control-Allow-Credentials: true
</pre>

<p><a class="internal" href="#Requests_with_credentials">Credentialed requests</a> are discussed above.</p>

<h3 id="Access-Control-Allow-Methods">Access-Control-Allow-Methods</h3>

<p>The {{HTTPHeader("Access-Control-Allow-Methods")}} header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.</p>

<pre class="brush: none">Access-Control-Allow-Methods: &lt;method&gt;[, &lt;method&gt;]*
</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="brush: none">Access-Control-Allow-Headers: &lt;field-name&gt;[, &lt;field-name&gt;]*
</pre>

<h2 id="The_HTTP_request_headers">The HTTP request headers</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="brush: none">Origin: &lt;origin&gt;
</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="brush: none">Access-Control-Request-Method: &lt;method&gt;
</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="brush: none">Access-Control-Request-Headers: &lt;field-name&gt;[, &lt;field-name&gt;]*
</pre>

<p>Examples of this usage can be <a class="internal" href="#Preflighted_requests">found above</a>.</p>

<h2 id="Specifications">Specifications</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="Browser_compatibility">Browser compatibility</h2>

<p class="hidden">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>

<p>{{Compat("http.headers.Access-Control-Allow-Origin")}}</p>

<h3 id="Compatibility_notes">Compatibility notes</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 <code>XMLHttpRequests</code> 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="See_also">See also</h2>

<ul>
 <li><a href="/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="/en-US/docs/Web/API/Fetch_API">Fetch API</a></li>
 <li><a class="external" 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>
  <ul>
  </ul>
 </li>
 <li><a class="external" 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 &amp; Server-Side (Java) sample for Cross-Origin Resource Sharing (CORS)</a></li>
 <li><a class="internal" href="/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>

<div>{{HTTPSidebar}}</div>