Cross-Origin Resource Sharing (CORS)
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since иÑÐ»Ñ 2015 г..
Cross-Origin Resource Sharing (CORS) â Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼, иÑполÑзÑÑÑий дополниÑелÑнÑе HTTP-заголовки, ÑÑÐ¾Ð±Ñ Ð´Ð°ÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð°Ð³ÐµÐ½ÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¿Ð¾Ð»ÑÑаÑÑ ÑазÑеÑÐµÐ½Ð¸Ñ Ð½Ð° доÑÑÑп к вÑбÑаннÑм ÑеÑÑÑÑам Ñ ÑеÑвеÑа на иÑÑоÑнике (домене), оÑлиÑном Ð¾Ñ Ñого, ÑÑо ÑÐ°Ð¹Ñ Ð¸ÑполÑзÑÐµÑ Ð² даннÑй моменÑ. ÐовоÑÑÑ, ÑÑо Ð°Ð³ÐµÐ½Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð´ÐµÐ»Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ñ Ð´ÑÑгого иÑÑоÑника (cross-origin HTTP request), еÑли иÑÑоÑник ÑекÑÑего докÑменÑа оÑлиÑаеÑÑÑ Ð¾Ñ Ð·Ð°Ð¿ÑаÑиваемого ÑеÑÑÑÑа доменом, пÑоÑоколом или поÑÑом.
ÐÑÐ¸Ð¼ÐµÑ cross-origin запÑоÑа: HTML ÑÑÑаниÑа, обÑлÑÐ¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ ÑеÑвеÑом Ñ http://domain-a.com, запÑаÑÐ¸Ð²Ð°ÐµÑ <img> src по адÑеÑÑ http://domain-b.com/image.jpg. Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð¼Ð½Ð¾Ð³Ð¸Ðµ ÑÑÑаниÑÑ Ð·Ð°Ð³ÑÑжаÑÑ ÑеÑÑÑÑÑ Ð²Ñоде CSS-ÑÑилей, изобÑажений и ÑкÑипÑов Ñ ÑазнÑÑ
доменов, ÑооÑвеÑÑÑвÑÑÑиÑ
ÑазнÑм ÑеÑÑм доÑÑавки конÑенÑа (Content delivery networks, CDNs).
Ð ÑелÑÑ
безопаÑноÑÑи бÑаÑзеÑÑ Ð¾Ð³ÑаниÑиваÑÑ cross-origin запÑоÑÑ, иниÑииÑÑемÑе ÑкÑипÑами. ÐапÑимеÑ, XMLHttpRequest и Fetch API ÑледÑÑÑ Ð¿Ð¾Ð»Ð¸Ñике одного иÑÑоÑника (same-origin policy). ÐÑо знаÑиÑ, ÑÑо web-пÑиложениÑ, иÑполÑзÑÑÑие Ñакие API, могÑÑ Ð·Ð°Ð¿ÑаÑиваÑÑ HTTP-ÑеÑÑÑÑÑ ÑолÑко Ñ Ñого домена, Ñ ÐºÐ¾ÑоÑого бÑли загÑÑженÑ, пока не бÑдÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ñ CORS-заголовки.

ÐеÑ
анизм CORS поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÐºÑоÑÑ-доменнÑе запÑоÑÑ Ð¸ пеÑедаÑÑ Ð´Ð°Ð½Ð½ÑÑ
Ð¼ÐµÐ¶Ð´Ñ Ð±ÑаÑзеÑом и web-ÑеÑвеÑами по заÑиÑÑÐ½Ð½Ð¾Ð¼Ñ ÑоединениÑ. СовÑеменнÑе бÑаÑзеÑÑ Ð¸ÑполÑзÑÑÑ CORS в API-конÑейнеÑаÑ
, ÑакиÑ
как XMLHttpRequest или Fetch, ÑÑÐ¾Ð±Ñ ÑнизиÑÑ ÑиÑки, пÑиÑÑÑие запÑоÑам Ñ Ð´ÑÑгиÑ
иÑÑоÑников.
ÐÑо должен ÑиÑаÑÑ Ð´Ð°Ð½Ð½ÑÑ ÑÑаÑÑÑ?
Ðа Ñамом деле, вÑе.
ÐонкÑеÑнее, ÑÑа ÑÑаÑÑÑ Ð´Ð»Ñ web-админиÑÑÑаÑоÑов, ÑазÑабоÑÑиков ÑеÑвеÑной ÑÑоÑÐ¾Ð½Ñ Ð¸ front-end ÑазÑабоÑÑиков. СовÑеменнÑе бÑаÑзеÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ ÐºÐ»Ð¸ÐµÐ½ÑÑкие компоненÑÑ cross-origin обмена, вклÑÑÐ°Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¸ и ÑоблÑдение пÑавил полиÑики. Ðо ÑÑÐ¾Ñ Ð½Ð¾Ð²Ñй ÑÑандаÑÑ Ð¾Ð·Ð½Ð°ÑаеÑ, ÑÑо ÑеÑвеÑа Ñакже Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ Ð½Ð¾Ð²Ñе заголовки запÑоÑов и оÑвеÑов. ÐÑÑÐ³Ð°Ñ ÑÑаÑÑÑ Ð´Ð»Ñ ÑазÑабоÑÑиков ÑеÑвеÑной ÑаÑÑи, опиÑÑваÑÑÐ°Ñ Ð¿ÐµÑÑпекÑÐ¸Ð²Ñ cross-origin обмена на ÑÑоÑоне ÑеÑвеÑа (Ñ Ð¿ÑимеÑами кода на PHP), к дополниÑелÑÐ½Ð¾Ð¼Ñ Ð¿ÑоÑÑениÑ.
Ðакие запÑоÑÑ Ð¸ÑполÑзÑÑÑ CORS?
ÐÑÐ¾Ñ ÑÑандаÑÑ cross-origin обмена иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑазÑеÑÐµÐ½Ð¸Ñ ÐºÑоÑÑ-ÑайÑовÑÑ HTTP запÑоÑов длÑ:
- ÐÑзова
XMLHttpRequestили Fetch APIs в кÑоÑÑ-ÑÐ°Ð¹Ñ Ð¼Ð°Ð½ÐµÑе, как опиÑано вÑÑе. - Web Fonts (Ð´Ð»Ñ ÐºÑоÑÑ-доменного иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑиÑÑов в
@font-faceв ÑÐ°Ð¼ÐºÐ°Ñ CSS), ÑÑÐ¾Ð±Ñ ÑеÑвеÑÑ Ð¼Ð¾Ð³Ð»Ð¸ ÑазвоÑаÑиваÑÑ TrueType ÑÑиÑÑÑ, коÑоÑÑе могÑÑ Ð±ÑÑÑ Ð·Ð°Ð³ÑÑÐ¶ÐµÐ½Ñ ÑолÑко кÑоÑÑ-ÑÐ°Ð¹Ñ Ð¸ иÑполÑÐ·Ð¾Ð²Ð°Ð½Ñ web-ÑайÑами, коÑоÑÑм ÑÑо ÑазÑеÑено. - WebGL ÑекÑÑÑÑÑ.
- ФÑÐµÐ¹Ð¼Ñ Ñ Ð¸Ð·Ð¾Ð±ÑажениÑми/видео, добавленнÑми в ÐºÐ°Ð½Ð²Ð°Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ
drawImage. - СÑили (Ð´Ð»Ñ CSSOM доÑÑÑпа).
- СкÑипÑÑ (Ð´Ð»Ñ Ð¾ÑклÑÑÑннÑÑ Ð¸ÑклÑÑений).
ÐÑа ÑÑаÑÑÑ Ð¾Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ Ð¾Ð±Ñие понÑÑÐ¸Ñ Cross-Origin Resource Sharing и вклÑÑÐ°ÐµÑ Ð¾Ð±ÑÑждение Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ÑÑ HTTP заголовков.
ÐÐ±Ð·Ð¾Ñ ÑÑнкÑионалÑноÑÑи
СÑандаÑÑ Cross-Origin Resource Sharing ÑабоÑÐ°ÐµÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²ÑÑ
HTTP-заголовков, коÑоÑÑе позволÑÑÑ ÑеÑвеÑам опиÑÑваÑÑ Ð½Ð°Ð±Ð¾Ñ Ð¸ÑÑоÑников, коÑоÑÑм ÑазÑеÑено ÑиÑаÑÑ Ð¸Ð½ÑоÑмаÑиÑ, запÑаÑиваемÑÑ web-бÑаÑзеÑом. Ð ÑаÑÑноÑÑи, Ð´Ð»Ñ Ð¼ÐµÑодов HTTP-запÑоÑов, коÑоÑÑе могÑÑ Ð¿ÑивеÑÑи к побоÑнÑм ÑÑÑекÑам над даннÑми ÑеÑвеÑа (в ÑаÑÑноÑÑи, Ð´Ð»Ñ HTTP меÑодов, оÑлиÑнÑÑ
Ð¾Ñ GET или Ð´Ð»Ñ POST запÑоÑов, иÑполÑзÑÑÑиÑ
опÑеделÑннÑе MIME-ÑипÑ), ÑпеÑиÑикаÑÐ¸Ñ ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ Ð±ÑаÑзеÑÑ "пÑедпÑовеÑÑли" запÑоÑ, запÑаÑÐ¸Ð²Ð°Ñ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑие меÑÐ¾Ð´Ñ Ñ ÑеÑвеÑа Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼ÐµÑода HTTP-запÑоÑа OPTIONS и заÑем, повеÑÑ
"подÑвеÑждениÑ" Ñ ÑеÑвеÑа, оÑÑÑлали ÑакÑиÑеÑкий запÑÐ¾Ñ Ñ ÑакÑиÑеÑким меÑодом HTTP-запÑоÑа. СеÑвеÑа Ñакже могÑÑ Ð¾Ð¿Ð¾Ð²ÐµÑаÑÑ ÐºÐ»Ð¸ÐµÐ½Ñов Ð´Ð¾Ð»Ð¶Ð½Ñ Ð»Ð¸ "полномоÑиÑ" (вклÑÑÐ°Ñ Cookies и HTTP Authentication даннÑе) бÑÑÑ Ð¾ÑпÑÐ°Ð²Ð»ÐµÐ½Ñ Ñ Ð·Ð°Ð¿ÑоÑом.
СледÑÑÑÐ°Ñ ÑекÑÐ¸Ñ Ð¾Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ ÑÑенаÑии, а Ñакже пÑедоÑÑавлÑÐµÑ Ð°Ð½Ð°Ð»Ð¸Ð· иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ HTTP-заголовков.
ÐÑимеÑÑ ÑÑенаÑиев ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾ÑÑÑпом
ÐдеÑÑ Ð¼Ñ ÑаÑÑмоÑÑим ÑÑи ÑÑенаÑиÑ, коÑоÑÑе иллÑÑÑÑиÑÑÑÑ ÐºÐ°Ðº Cross-Origin Resource Sharing ÑабоÑаеÑ. ÐаждÑй ÑÑенаÑий иÑполÑзÑÐµÑ Ð¾Ð±ÑÐµÐºÑ XMLHttpRequest, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзован Ð´Ð»Ñ Ð¼ÐµÐ¶ÑайÑового взаимодейÑÑвиÑ, в лÑбом, поддеÑживаÑÑем даннÑй обÑекÑ, бÑаÑзеÑе.
ФÑагменÑÑ JavaScript-кода, вклÑÑÑннÑе в ÑÑи ÑекÑии (а Ñакже ÑÑагменÑÑ ÐºÐ¾Ð´Ð°, оÑвеÑаÑÑие за коÑÑекÑнÑÑ Ð¾Ð±ÑабоÑÐºÑ Ð¼ÐµÐ¶ÑеÑвеÑнÑÑ
запÑоÑов, коÑоÑÑе запÑÑкаÑÑÑÑ Ð½Ð° ÑеÑвеÑе) могÑÑ Ð±ÑÑÑ Ð¸ÑпÑÑÐ°Ð½Ñ "в дейÑÑвии" на http://arunranga.com/examples/access-control/, и бÑдÑÑ ÑабоÑаÑÑ Ð² бÑаÑзеÑаÑ
, коÑоÑÑе поддеÑживаÑÑ XMLHttpRequest.
ÐбÑÑждение Cross-Origin Resource Sharing Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ ÑеÑвеÑа (вклÑÑÐ°Ñ ÑÑагменÑÑ ÐºÐ¾Ð´Ð° на PHP) Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾ в ÑÑаÑÑе Server-Side Access Control (CORS).
ÐÑоÑÑÑе запÑоÑÑ
ÐекоÑоÑÑе запÑоÑÑ Ð½Ðµ заÑÑавлÑÑÑ ÑÑабаÑÑваÑÑ CORS preflight. Ðни назÑваÑÑÑÑ Ð¿ÑоÑÑÑми запÑоÑами ÑоглаÑно ÑÑÑаÑевÑей ÑпеÑиÑикаÑии CORS (англ.), Ñогда как ÑпеÑиÑикаÑÐ¸Ñ Fetch, коÑоÑÐ°Ñ Ð² наÑÑоÑÑее вÑÐµÐ¼Ñ Ð¾Ð¿ÑеделÑÐµÑ CORS, не иÑполÑзÑÐµÑ Ð´Ð°Ð½Ð½Ñй ÑеÑмин.
«ÐÑоÑÑой запÑоÑ» â ÑÑо запÑоÑ, ÑдовлеÑвоÑÑÑÑий ÑледÑÑÑим ÑÑловиÑм:
-
ÐопÑÑÑимÑе меÑÐ¾Ð´Ñ Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа:
-
ÐÑоме заголовков, коÑоÑÑе авÑомаÑиÑеÑки пÑоÑÑавлÑÑÑÑÑ user-agent'ом (напÑимеÑ,
Connection,User-Agent, или лÑбой дÑÑгой заголовок Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼, опÑеделÑннÑм в ÑпеÑиÑикаÑии меÑода Fetch в ÑекÑии "ÐапÑеÑÑннÑе имена заголовков (коÑоÑÑе нелÑÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ Ð¿ÑогÑаммно)"), допÑÑÑимÑми заголовками, коÑоÑÑе могÑÑ Ð±ÑÑÑ Ð¿ÑоÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð²ÑÑÑнÑÑ, ÑвлÑÑÑÑÑ Ñе заголовки, коÑоÑÑе опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ ÑпеÑиÑикаÑией меÑода Fetch как "CORS-безопаÑнÑе заголовки запÑоÑа", Ñакие как:AcceptAccept-LanguageContent-LanguageContent-Type(но ÑÑиÑÑвайÑе пÑимеÑание ниже)
-
ÐопÑÑÑимÑми знаÑениÑми заголовка
Content-TypeÑвлÑÑÑÑÑ:application/x-www-form-urlencodedmultipart/form-datatext/plain
-
Ðе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð·Ð°ÑегиÑÑÑиÑÐ¾Ð²Ð°Ð½Ñ Ð¾Ð±ÑабоÑÑики ÑобÑÑий на лÑбой обÑекÑ
XMLHttpRequestUploadиÑполÑзÑемÑй в запÑоÑе; ÑÑо доÑÑигаеÑÑÑ Ð¸ÑполÑзованием ÑвойÑÑваXMLHttpRequest.upload. -
РзапÑоÑе не должен иÑполÑзоваÑÑÑÑ Ð¾Ð±ÑÐµÐºÑ Ñипа
ReadableStream.
ÐÑимеÑание: These are the same kinds of cross-site requests that web content can already issue, and no response data is released to the requester unless the server sends an appropriate header. Therefore, sites that prevent cross-site request forgery have nothing new to fear from HTTP access control.
ÐÑимеÑание:
WebKit Nightly и Safari Technology Preview ÑÑÑанавливаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе огÑаниÑÐµÐ½Ð¸Ñ Ð½Ð° знаÑениÑ, допÑÑÑимÑе в заголовкаÑ
Accept, Accept-Language, и Content-Language. ÐÑли лÑбой из ÑÑиÑ
заголовков Ð¸Ð¼ÐµÐµÑ "неÑÑандаÑÑное" знаÑение, WebKit/Safari иÑполÑзÑÑÑ Ð¿ÑедваÑиÑелÑнÑй запÑоÑ. ÐнаÑениÑ, коÑоÑÑе WebKit/Safari ÑÑиÑаÑÑ "неÑÑандаÑÑнÑми" Ð´Ð»Ñ ÑÑиÑ
заголовков, пеÑеÑиÑÐ»ÐµÐ½Ñ ÑолÑко в ÑледÑÑÑиÑ
пÑоблемаÑ
WebKit: Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, и Switch to a blacklist model for restricted Accept headers in simple CORS requests. Ðо вÑеÑ
дÑÑгиÑ
бÑаÑзеÑаÑ
подобнÑÑ
дополниÑелÑнÑÑ
огÑаниÑений неÑ, поÑÐ¾Ð¼Ñ ÑÑо они не ÑвлÑÑÑÑÑ ÑаÑÑÑÑ ÑпеÑиÑикаÑии.
ÐапÑимеÑ, пÑедÑÑавÑÑе, ÑÑо ÑодеÑжимое домена http://foo.example Ñ
оÑÐµÑ Ð¾Ð±ÑаÑиÑÑÑÑ Ðº ÑодеÑÐ¶Ð¸Ð¼Ð¾Ð¼Ñ http://bar.other. Ðа домене http://foo.example Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ ÑледÑÑÑий Javascript код:
const xhr = new XMLHttpRequest();
const url = "https://bar.other/resources/public-data/";
xhr.open("GET", url);
xhr.onreadystatechange = someHandler;
xhr.send();
ÐÑо пÑиведÑÑ Ðº пÑоÑÑÐ¾Ð¼Ñ Ð¾Ð±Ð¼ÐµÐ½Ñ Ð·Ð°Ð¿ÑоÑами Ð¼ÐµÐ¶Ð´Ñ ÐºÐ»Ð¸ÐµÐ½Ñом и ÑеÑвеÑом, иÑполÑзÑÑ CORS заголовки Ð´Ð»Ñ Ð¾Ð±ÑабоÑки пÑивилегий:

ÐоÑмоÑÑим, ÑÑо бÑаÑÐ·ÐµÑ Ð¾ÑпÑÐ°Ð²Ð¸Ñ Ð² Ñаком ÑлÑÑае на ÑеÑвеÑ, а Ñакже пÑовеÑим оÑÐ²ÐµÑ ÑеÑвеÑа:
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 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]
СÑÑоÑки 1 - 10 ÑÑо заголовки оÑпÑавленного запÑоÑа. СамÑм инÑеÑеÑÑÑÑим здеÑÑ Ð´Ð»Ñ Ð½Ð°Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð¼ ÑвлÑеÑÑÑ Origin, ÑказаннÑй на 10 ÑÑÑоке. ÐаннÑй заголовок ÑказÑваеÑ, ÑÑо запÑÐ¾Ñ Ð¿ÑиÑÑл из ÑодеÑжимого домена http://foo.example.
СÑÑоÑки 13 - 22 показÑваÑÑ HTTP-оÑÐ²ÐµÑ Ð¾Ñ ÑеÑвеÑа на домен http://bar.other. РоÑÐ²ÐµÑ ÑеÑÐ²ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Access-Control-Allow-Origin заголовок, ÑказаннÑй на 16 ÑÑÑоке. ÐÑполÑзование заголовков Origin header и Access-Control-Allow-Origin показÑÐ²Ð°ÐµÑ Ð¿ÑоÑокол конÑÑÐ¾Ð»Ñ Ð´Ð¾ÑÑÑпа в пÑоÑÑейÑем виде. Ð ÑÑом ÑлÑÑае, ÑеÑÐ²ÐµÑ Ð¾ÑвеÑÐ°ÐµÑ Ñ Access-Control-Allow-Origin: * ÑÑо ознаÑаеÑ, ÑÑо к ÑеÑÑÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп Ñ Ð»Ñбого домена кÑоÑÑ-ÑайÑовÑм ÑпоÑобом. ÐÐ»Ð°Ð´ÐµÐ»ÐµÑ ÑеÑÑÑÑа http://bar.other Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð³ÑаниÑиÑÑ Ð´Ð¾ÑÑÑп к ÑеÑÑÑÑÑ Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑов ÑолÑко Ñ http://foo.example, Ñказав:
Access-Control-Allow-Origin: http://foo.example
ÐÑмеÑÑÑе, никакой домен, кÑоме http://foo.example (опÑеделÑн ORIGIN: заголовок в запÑоÑе, как в 10 ÑÑÑоке вÑÑе), не Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп к ÑеÑÑÑÑÑ ÐºÑоÑÑ-ÑайÑовÑм ÑпоÑобом. Ðаголовок Access-Control-Allow-Origin должен ÑодеÑжаÑÑ Ð·Ð½Ð°Ñение, коÑоÑое бÑло оÑпÑавлено в заголовке Origin запÑоÑа.
ÐÑедваÑиÑелÑнÑе запÑоÑÑ
РоÑлиÑие Ð¾Ñ Ð¿ÑоÑÑÑÑ
запÑоÑов, Ð´Ð»Ñ "пÑедваÑиÑелÑнÑÑ
" запÑоÑов бÑаÑÐ·ÐµÑ ÑнаÑала оÑпÑавлÑÐµÑ HTTP-запÑÐ¾Ñ Ñ Ð¸ÑполÑзованием меÑода OPTIONS к ÑеÑÑÑÑÑ Ð½Ð° дÑÑгом домене, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, ÑвлÑеÑÑÑ Ð»Ð¸ ÑакÑиÑеÑкий запÑÐ¾Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑнÑм Ð´Ð»Ñ Ð¾ÑпÑавки. Такие запÑоÑÑ Ðº ÑазнÑм иÑÑоÑникам пÑоÑ
одÑÑ Ð¿ÑедваÑиÑелÑнÑÑ Ð¿ÑовеÑкÑ, поÑколÑÐºÑ Ð¾Ð½Ð¸ могÑÑ Ð²Ð»Ð¸ÑÑÑ Ð½Ð° полÑзоваÑелÑÑкие даннÑе.
Ð ÑаÑÑноÑÑи, запÑÐ¾Ñ Ð¿ÑедваÑиÑелÑно пÑоÑмаÑÑиваеÑÑÑ, еÑли вÑполнÑеÑÑÑ Ð»Ñбое из ÑледÑÑÑÐ¸Ñ ÑÑловий:
-
ÐÑли в запÑоÑе иÑполÑзÑеÑÑÑ Ð»Ñбой из ÑледÑÑÑÐ¸Ñ Ð¼ÐµÑодов:
-
Ðли еÑли, кÑоме заголовков, авÑомаÑиÑеÑки ÑÑÑанавливаемÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑким агенÑом (напÑимеÑ,
Connection,User-Agent, или лÑбÑм дÑÑгим заголовком Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼, опÑеделÑннÑм в ÑпеÑиÑикаÑии Fetch как "Ð¸Ð¼Ñ Ð·Ð°Ð¿ÑеÑÑнного заголовка"), запÑÐ¾Ñ Ð²ÐºÐ»ÑÑÐ°ÐµÑ Ð»ÑбÑе заголовки, оÑлиÑнÑе Ð¾Ñ ÑÐµÑ , коÑоÑÑе ÑпеÑиÑикаÑÐ¸Ñ Fetch опÑеделÑÐµÑ ÐºÐ°Ðº "заголовок запÑоÑа CORS-безопаÑнÑй заголовок запÑоÑа", а именно:AcceptAccept-LanguageContent-LanguageContent-Type(но ÑÑÑиÑе дополниÑелÑнÑе ÑÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð¸Ð¶Ðµ)Last-Event-IDDPRSave-DataViewport-WidthWidth
-
Ðли еÑли заголовок
Content-TypeÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°Ñение, оÑлиÑное Ð¾Ñ ÑледÑÑÑÐ¸Ñ :application/x-www-form-urlencodedmultipart/form-datatext/plain
-
Ðли еÑли один или болÑÑе обÑабоÑÑиков ÑобÑÑий заÑегиÑÑÑиÑÐ¾Ð²Ð°Ð½Ñ Ð½Ð° обÑекÑе
XMLHttpRequestUpload, коÑоÑÑй иÑполÑзÑеÑÑÑ Ð² запÑоÑе. -
Ðли еÑли обÑекÑ
ReadableStreamиÑполÑзÑеÑÑÑ Ð² запÑоÑе.
Ðиже пÑиведÑн пÑÐ¸Ð¼ÐµÑ Ð·Ð°Ð¿ÑоÑа, коÑоÑÑй бÑÐ´ÐµÑ Ð¿ÑедваÑиÑелÑно пÑоÑмоÑÑен.
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);
}
}
......
РпÑимеÑе вÑÑе, 3 ÑÑÑока ÑоздаÑÑ XML Ñело, ÑÑÐ¾Ð±Ñ Ð¾ÑпÑавиÑÑ POST запÑоÑом на ÑÑÑоке 8. Также, на ÑÑÑоке 9, "каÑÑомизиÑованнÑй" (не ÑÑандаÑÑнÑй) заголовок HTTP запÑоÑа ÑÑÑановлен (X-PINGOTHER: pingpong). Такие заголовки не ÑвлÑÑÑÑÑ ÑаÑÑÑÑ Ð¿ÑоÑокола HTTP/1.1, но, как пÑавило, Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð´Ð»Ñ Ð²ÐµÐ±-пÑиложений. Так как запÑÐ¾Ñ Ð¸ÑполÑзÑÐµÑ Content-Type application/xml, и Ñак как ÑÑÑановлен каÑÑомизиÑованнÑй заголовок, ÑÑÐ¾Ñ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¿ÑоÑмаÑÑиваеÑÑÑ.

ÐÑимеÑание:
Ðак опиÑано ниже, ÑакÑиÑеÑкий POST запÑÐ¾Ñ Ð½Ðµ вклÑÑÐ°ÐµÑ Access-Control-Request-* заголовки; они нÑÐ¶Ð½Ñ ÑолÑко Ð´Ð»Ñ OPTIONS запÑоÑа.
ÐавайÑе поÑмоÑÑим на полнÑй обмен Ð¼ÐµÐ¶Ð´Ñ ÐºÐ»Ð¸ÐµÐ½Ñом и ÑеÑвеÑом. ÐеÑвÑй обмен - ÑÑо пÑедваÑиÑелÑнÑй запÑоÑ/оÑвеÑ:
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 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
Ðак ÑолÑко пÑедваÑиÑелÑнÑй запÑÐ¾Ñ Ð·Ð°Ð²ÐµÑÑÑн, оÑпÑавлÑеÑÑÑ Ð½Ð°ÑÑоÑÑий запÑоÑ:
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 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]
СÑÑоки 1 - 12 вÑÑе пÑедÑÑавлÑÑÑ Ð¿ÑедваÑиÑелÑнÑй запÑÐ¾Ñ Ñ OPTIONS меÑодом. ÐÑаÑÐ·ÐµÑ Ð¾Ð¿ÑеделÑеÑ, ÑÑо ÐµÐ¼Ñ Ð½Ñжно оÑпÑавиÑÑ ÑÑо, оÑновÑваÑÑÑ Ð½Ð° паÑамеÑÑаÑ
запÑоÑа, коÑоÑÑе иÑполÑзовалиÑÑ Ð²Ð¾ ÑÑагменÑе кода JavaScript вÑÑе, ÑÑÐ¾Ð±Ñ ÑеÑÐ²ÐµÑ Ð¼Ð¾Ð³ оÑвеÑиÑÑ, допÑÑÑимо ли оÑпÑавиÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ñ ÑакÑиÑеÑкими паÑамеÑÑами запÑоÑа. OPTIONS - ÑÑо меÑод HTTP/1.1, коÑоÑÑй иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑной инÑоÑмаÑии Ð¾Ñ ÑеÑвеÑов, и ÑвлÑеÑÑÑ safe меÑодом, ÑÑо ознаÑаеÑ, ÑÑо его нелÑÐ·Ñ Ð¸ÑполÑзоваÑÑ Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑеÑÑÑÑа. ÐбÑаÑиÑе внимание, ÑÑо вмеÑÑе Ñ Ð·Ð°Ð¿ÑоÑом OPTIONS оÑпÑавлÑÑÑÑÑ Ð´Ð²Ð° дÑÑгиÑ
заголовка запÑоÑа (ÑÑÑоки 10 и 11 ÑооÑвеÑÑÑвенно):
Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER, Content-Type
Ðаголовок Access-Control-Request-Method ÑведомлÑÐµÑ ÑеÑÐ²ÐµÑ ÐºÐ°Ðº ÑаÑÑÑ Ð¿ÑедваÑиÑелÑного запÑоÑа о Ñом, ÑÑо пÑи оÑпÑавке ÑакÑиÑеÑкого запÑоÑа он бÑÐ´ÐµÑ Ð¾ÑпÑавлен меÑодом запÑоÑа POST. Ðаголовок Access-Control-Request-Headers ÑведомлÑÐµÑ ÑеÑÐ²ÐµÑ Ð¾ Ñом, ÑÑо пÑи оÑпÑавке ÑакÑиÑеÑкого запÑоÑа он бÑÐ´ÐµÑ Ð¾ÑпÑавлен Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкими заголовками X-PINGOTHER и Content-Type. ТепеÑÑ Ñ ÑеÑвеÑа еÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¾Ð¿ÑеделиÑÑ, Ñ
оÑÐµÑ Ð»Ð¸ он пÑинÑÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð² ÑÑиÑ
обÑÑоÑÑелÑÑÑваÑ
.
СÑÑоки 14 - 26 вÑÑе - ÑÑо оÑвеÑ, коÑоÑÑй ÑеÑÐ²ÐµÑ Ð¾ÑпÑавлÑÐµÑ Ð¾Ð±ÑаÑно, ÑказÑваÑ, ÑÑо меÑод запÑоÑа (POST) и заголовки запÑоÑа (X-PINGOTHER) ÑвлÑÑÑÑÑ Ð¿ÑиемлемÑми. Ð ÑаÑÑноÑÑи, давайÑе поÑмоÑÑим на ÑÑÑоки 17-20:
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
СеÑÐ²ÐµÑ Ð¾ÑвеÑÐ°ÐµÑ Ñ Access-Control-Allow-Methods и ÑообÑаеÑ, ÑÑо POST, GET, и OPTIONS ÑвлÑÑÑÑÑ Ð¶Ð¸Ð·Ð½ÐµÑпоÑобнÑми меÑодами Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа ÑооÑвеÑÑÑвÑÑÑего ÑеÑÑÑÑа. ÐбÑаÑиÑе внимание, ÑÑо ÑÑÐ¾Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº поÑ
ож на заголовок оÑвеÑа Allow, но иÑполÑзÑеÑÑÑ ÑÑÑого в конÑекÑÑе конÑÑÐ¾Ð»Ñ Ð´Ð¾ÑÑÑпа.
СеÑÐ²ÐµÑ Ñакже оÑпÑавлÑÐµÑ Access-Control-Allow-Headers Ñо знаÑением "X-PINGOTHER, Content-Type", подÑвеÑждаÑ, ÑÑо ÑÑо ÑазÑеÑÑннÑе заголовки, коÑоÑÑе бÑдÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ñ ÑакÑиÑеÑким запÑоÑом. Ðак и Access-Control-Allow-Methods, Access-Control-Allow-Headers пÑедÑÑавлÑÐµÑ Ñобой ÑпиÑок допÑÑÑимÑÑ
заголовков ÑеÑез запÑÑÑÑ.
ÐаконеÑ, Access-Control-Max-Age даÑÑ Ð·Ð½Ð°Ñение в ÑекÑндаÑ
, в ÑеÑение коÑоÑого можно кеÑиÑоваÑÑ Ð¾ÑÐ²ÐµÑ Ð½Ð° пÑедваÑиÑелÑнÑй запÑÐ¾Ñ Ð±ÐµÐ· оÑпÑавки дÑÑгого пÑедваÑиÑелÑного запÑоÑа. Ð ÑÑом ÑлÑÑае, 86400 ÑекÑÐ½Ð´Ñ - ÑÑо 24 ÑаÑа. ÐбÑаÑиÑе внимание, ÑÑо каждÑй бÑаÑÐ·ÐµÑ Ð¸Ð¼ÐµÐµÑ Ð¼Ð°ÐºÑималÑное внÑÑÑеннее знаÑение, коÑоÑое Ð¸Ð¼ÐµÐµÑ Ð¿ÑиоÑиÑеÑ, когда Access-Control-Max-Age болÑÑе.
ÐÑедваÑиÑелÑнÑе запÑоÑÑ Ð¸ пеÑеадÑеÑаÑии
ÐолÑÑинÑÑво бÑаÑзеÑов в наÑÑоÑÑее вÑÐµÐ¼Ñ Ð½Ðµ поддеÑживаÑÑ ÑледÑÑÑие пеÑеадÑеÑаÑии Ð´Ð»Ñ Ð¿ÑедваÑиÑелÑнÑÑ Ð·Ð°Ð¿ÑоÑов. ÐÑли пеÑеадÑеÑаÑÐ¸Ñ Ð¿ÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ Ð¿ÑедваÑиÑелÑного запÑоÑа, болÑÑинÑÑво ÑовÑеменнÑÑ Ð±ÑаÑзеÑов ÑообÑÐ°Ñ Ð¾Ð± оÑибке, Ñакой как ÑледÑÑÑее.
ÐапÑÐ¾Ñ Ð±Ñл пеÑенапÑавлен на 'https://example.com/foo', коÑоÑÑй запÑеÑÑн Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑов из ÑазнÑÑ Ð¸ÑÑоÑников, ÑÑебÑÑÑÐ¸Ñ Ð¿ÑедваÑиÑелÑной пÑовеÑки
ÐапÑÐ¾Ñ ÑÑебÑÐµÑ Ð¿ÑедваÑиÑелÑной пÑовеÑки, коÑоÑÐ°Ñ Ð·Ð°Ð¿ÑеÑена Ð´Ð»Ñ Ð¿ÐµÑенапÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñ Ð¸ÑÑоÑниками
ÐÑоÑокол CORS изнаÑалÑно ÑÑебовал Ñакого поведениÑ, но впоÑледÑÑвии бÑл изменÑн, ÑÑÐ¾Ð±Ñ Ð±Ð¾Ð»ÑÑе не ÑÑебоваÑÑ ÐµÐ³Ð¾. Ðднако болÑÑинÑÑво бÑаÑзеÑов еÑÑ Ð½Ðµ Ñеализовали ÑÑо изменение и вÑе еÑÑ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑиÑÑÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ, коÑоÑое ÑÑебовалоÑÑ Ð¸Ð·Ð½Ð°ÑалÑно.
ÐоÑÑомÑ, пока бÑаÑзеÑÑ Ð½Ðµ догонÑÑ ÑпеÑиÑикаÑиÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе обойÑи ÑÑо огÑаниÑение, вÑполнив одно или оба из ÑледÑÑÑÐ¸Ñ Ð´ÐµÐ¹ÑÑвий:
- измениÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ на ÑÑоÑоне ÑеÑвеÑа, ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð¿ÑедваÑиÑелÑной пÑовеÑки и/или избежаÑÑ Ð¿ÐµÑеадÑеÑаÑии â еÑли Ñ Ð²Ð°Ñ ÐµÑÑÑ ÐºÐ¾Ð½ÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ ÑеÑвеÑом, к коÑоÑÐ¾Ð¼Ñ Ð´ÐµÐ»Ð°ÐµÑÑÑ Ð·Ð°Ð¿ÑоÑ
- измениÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ñак, ÑÑÐ¾Ð±Ñ ÑÑо бÑл пÑоÑÑой запÑоÑ, коÑоÑÑй не вÑзÑÐ²Ð°ÐµÑ Ð¿ÑедваÑиÑелÑнÑÑ Ð¿ÑовеÑкÑ
Ðо еÑли невозможно внеÑÑи ÑÑи изменениÑ, Ñо возможен дÑÑгой ÑпоÑоб:
- СделайÑе пÑоÑÑой запÑÐ¾Ñ Ð¸ÑполÑзÑÑ Response.url Ð´Ð»Ñ Fetch API или XHR.responseURL, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, на каком URL завеÑÑиÑÑÑ Ð½Ð°ÑÑоÑÑий пÑедваÑиÑелÑнÑй запÑоÑ.
- СделайÑе дÑÑгой запÑÐ¾Ñ ("наÑÑоÑÑий" запÑоÑ), иÑполÑзÑÑ URL адÑеÑ, полÑÑеннÑй из Response.url или XMLHttpRequest.responseURL на пеÑвом ÑÑапе.
Ðднако, еÑли запÑÐ¾Ñ Ð¸Ð½Ð¸ÑииÑÑÐµÑ Ð¿ÑедваÑиÑелÑнÑÑ Ð¿ÑовеÑÐºÑ Ð¸Ð·-за налиÑÐ¸Ñ Ð² запÑоÑе заголовка Authorization, Ð²Ñ Ð½Ðµ ÑможеÑе обойÑи огÑаниÑение, иÑполÑзÑÑ Ð¾Ð¿Ð¸ÑаннÑе вÑÑе Ñаги. Ð Ð²Ñ Ð²Ð¾Ð¾Ð±Ñе не ÑможеÑе обойÑи ÑÑо, еÑли Ñ Ð²Ð°Ñ Ð½ÐµÑ ÐºÐ¾Ð½ÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ ÑеÑвеÑом, на коÑоÑÑй делаеÑÑÑ Ð·Ð°Ð¿ÑоÑ.
ÐапÑоÑÑ Ñ ÑÑÑÑнÑми даннÑми
Ðаиболее инÑеÑеÑÐ½Ð°Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ, пÑедоÑÑавлÑÐµÐ¼Ð°Ñ ÐºÐ°Ðº XMLHttpRequest, Ñак и Fetch и CORS - ÑÑо возможноÑÑÑ Ð´ÐµÐ»Ð°ÑÑ "пÑовеÑеннÑе" запÑоÑÑ, коÑоÑÑе оÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ñ Ð¾ ÑайлаÑ
HTTP cookie и инÑоÑмаÑии HTTP аÑÑенÑиÑикаÑии. Ðо ÑмолÑаниÑ, в кÑоÑÑ-ÑайÑовÑÑ
XMLHttpRequest или Fetch вÑзоваÑ
, бÑаÑзеÑÑ Ð½Ðµ оÑпÑавлÑÑÑ ÑÑÑÑнÑе даннÑе. ÐонкÑеÑнÑй Ñлаг должен бÑÑÑ ÑÑÑановлен Ð´Ð»Ñ Ð¾Ð±ÑекÑа XMLHttpRequest или конÑÑÑÑкÑоÑа Request пÑи его вÑзове.
Ð ÑÑом пÑимеÑе конÑенÑ, изнаÑалÑно загÑÑженнÑй из http://foo.example, вÑполнÑÐµÑ Ð¿ÑоÑÑой GET запÑÐ¾Ñ Ðº ÑеÑÑÑÑÑ http://bar.other, коÑоÑÑй ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑÐ°Ð¹Ð»Ñ cookie. СодеÑжимое на foo.example Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ñакой JavaScript:
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();
}
}
Ð ÑÑÑоке 7 показан Ñлаг XMLHttpRequest, коÑоÑÑй должен бÑÑÑ ÑÑÑановлен Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ñзова Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñайлов cookie, а именно логиÑеÑкое знаÑение withCredentials. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð²Ñзов вÑполнÑеÑÑÑ Ð±ÐµÐ· Ñайлов cookie. ÐоÑколÑÐºÑ ÑÑо пÑоÑÑой запÑÐ¾Ñ GET, он не ÑвлÑеÑÑÑ Ð¿ÑедваÑиÑелÑнÑм, но бÑаÑÐ·ÐµÑ Ð¾ÑклонÑÐµÑ Ð»Ñбой оÑвеÑ, коÑоÑÑй не Ð¸Ð¼ÐµÐµÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° Access-Control-Allow-Credentials: true, и не ÑоздаÑÑ Ð¾ÑвеÑ, доÑÑÑпнÑй Ð´Ð»Ñ Ð²Ñзова веб-конÑенÑа.

ÐÐ¾Ñ Ð¿ÑÐ¸Ð¼ÐµÑ Ð¾Ð±Ð¼ÐµÐ½Ð° Ð¼ÐµÐ¶Ð´Ñ ÐºÐ»Ð¸ÐµÐ½Ñом и ÑеÑвеÑом:
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 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]
Также в ÑÑÑоке 11 ÑодеÑжиÑÑÑ Cookie, пÑедназнаÑеннÑй Ð´Ð»Ñ ÐºÐ¾Ð½ÑенÑа ÑеÑÑÑÑа http://bar.other. Ð ÑлÑÑае еÑли http://bar.other не оÑвеÑÐ¸Ñ Ð¿Ð¾Ð»ÐµÐ¼ Access-Control-Allow-Credentials: true (ÑÑÑока 19), Ñо оÑÐ²ÐµÑ Ð¾Ñ ÑеÑвеÑа бÑÐ´ÐµÑ Ð¿ÑоигноÑиÑован и не ÑÑÐ°Ð½ÐµÑ Ð´Ð¾ÑÑÑпнÑм Ð´Ð»Ñ Ð²ÐµÐ±-конÑенÑа.
ÐапÑоÑÑ Ñ ÑÑÑÑнÑми даннÑми и wildcards
РпÑоÑеÑÑе оÑвеÑа на запÑÐ¾Ñ Ñ ÑÑÑÑнÑми даннÑми ÑеÑÐ²ÐµÑ Ð¾Ð±Ñзан ÑказаÑÑ ÑоÑнÑй иÑÑоÑник в поле заголовка Access-Control-Allow-Origin вмеÑÑо ÑпеÑÑимвола "*".
Ðз-за Ñого ÑÑо заголовки запÑоÑа в пÑимеÑе вÑÑе вклÑÑаÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Cookie, запÑÐ¾Ñ Ð¿ÑовалилÑÑ Ð±Ñ, еÑли Ð±Ñ Ð·Ð½Ð°Ñение заголовка Control-Allow-Origin бÑло "*". Ðо он не пÑовалилÑÑ: поÑÐ¾Ð¼Ñ ÑÑо знаÑение заголовка Access-Control-Allow-Origin - "http://foo.example" (дейÑÑвиÑелÑнÑй иÑÑоÑник), а не ÑпеÑÑимвол "*", конÑенÑ, ÑдоÑÑовеÑÑÑÑий полномоÑиÑ, возвÑаÑаеÑÑÑ Ð² вÑзÑваÑÑий веб-конÑенÑ.
ÐÑмеÑÑÑе, ÑÑо заголовок оÑвеÑа Set-Cookie в пÑимеÑе вÑÑе Ñакже ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе кÑки. Ð ÑлÑÑае неÑдаÑи, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð¸ÑклÑÑение, в завиÑимоÑÑи Ð¾Ñ Ð¸ÑполÑзÑемого API.
Ðаголовки HTTP оÑвеÑов
ÐÑа ÑекÑÐ¸Ñ ÑодеÑÐ¶Ð¸Ñ ÑпиÑок заголовков HTTP оÑвеÑов, коÑоÑÑе ÑеÑÐ²ÐµÑ ÑлÑÑ Ð² оÑÐ²ÐµÑ Ð½Ð° запÑÐ¾Ñ Ð´Ð¾ÑÑÑпа, как опиÑано в ÑпеÑиÑикаÑии ÑовмеÑÑного иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑеÑÑÑÑов Ð¼ÐµÐ¶Ð´Ñ ÑазнÑми иÑÑоÑниками. РпÑедÑдÑÑей ÑекÑии ÑÑо опиÑано в дейÑÑвии.
Access-Control-Allow-Origin
ÐозвÑаÑаемÑй ÑеÑÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¾Ð´Ð¸Ð½ заголовок Access-Control-Allow-Origin, ÑинÑакÑÐ¸Ñ ÐºÐ¾ÑоÑого:
Access-Control-Allow-Origin: <origin> | *
Access-Control-Allow-Origin опÑеделÑÐµÑ Ð»Ð¸Ð±Ð¾ один иÑÑоÑник, ÑÑо ÑказÑÐ²Ð°ÐµÑ Ð±ÑаÑзеÑÑ ÑазÑеÑиÑÑ ÑÑÐ¾Ð¼Ñ Ð¸ÑÑоÑÐ½Ð¸ÐºÑ Ð´Ð¾ÑÑÑп к ÑеÑÑÑÑÑ; либо â Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑов без ÑÑÑÑнÑÑ
даннÑÑ
â знаÑение "*", коÑоÑое говоÑÐ¸Ñ Ð±ÑаÑзеÑÑ ÑазÑеÑиÑÑ Ð·Ð°Ð¿ÑоÑÑ Ð¸Ð· лÑбÑÑ
иÑÑоÑников.
ÐапÑимеÑ, ÑÑÐ¾Ð±Ñ ÑазÑеÑиÑÑ http://mozilla.org доÑÑÑп к ÑеÑÑÑÑÑ, можно ÑказаÑÑ:
Access-Control-Allow-Origin: http://mozilla.org
ÐÑли ÑеÑÐ²ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ Ñ Ð¾ÑÑа, вмеÑÑо "*", Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñказан заголовок Vary Ñо знаÑением Origin, ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ ÐºÐ»Ð¸ÐµÐ½Ñам, ÑÑо оÑвеÑÑ Ñ ÑеÑвеÑа бÑдÑÑ Ð¾ÑлиÑаÑÑÑÑ Ð² завиÑимоÑÑи Ð¾Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° запÑоÑа Origin.
Access-Control-Expose-Headers
The Access-Control-Expose-Headers header lets a server whitelist headers that browsers are allowed to access. For example:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
This allows the X-My-Custom-Header and X-Another-Custom-Header headers to be exposed to the browser.
Access-Control-Max-Age
The 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.
Access-Control-Max-Age: <delta-seconds>
The delta-seconds parameter indicates the number of seconds the results can be cached.
Access-Control-Allow-Credentials
The Access-Control-Allow-Credentials header Indicates whether or not the response to the request can be exposed when the credentials 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 GET 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.
Access-Control-Allow-Credentials: true
Credentialed requests are discussed above.
Access-Control-Allow-Methods
The 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.
Access-Control-Allow-Methods: <method>[, <method>]*
An example of a preflight request is given above, including an example which sends this header to the browser.
Access-Control-Allow-Headers
The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
The HTTP request headers
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 XMLHttpRequest capability do not have to set any cross-origin sharing request headers programmatically.
Origin
The Origin header indicates the origin of the cross-site access request or preflight request.
Origin: <origin>
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.
ÐÑимеÑание:
The origin can be the empty string; this is useful, for example, if the source is a data URL.
Note that in any access control request, the Origin header is always sent.
Access-Control-Request-Method
The 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.
Access-Control-Request-Method: <method>
Examples of this usage can be found above.
Access-Control-Request-Headers
The 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.
Access-Control-Request-Headers: <field-name>[, <field-name>]*
Examples of this usage can be found above.
СпеÑиÑикаÑии
| Specification |
|---|
| Fetch > # http-access-control-allow-origin > |
СовмеÑÑимоÑÑÑ Ñ Ð±ÑаÑзеÑами
Compatibility notes
- Internet Explorer 8 and 9 expose CORS via the
XDomainRequestobject, but have a full implementation in IE 10. - 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
drawImage.
СмоÑÑиÑе Ñакже
- Code Samples Showing
XMLHttpRequestand Cross-Origin Resource Sharing - Cross-Origin Resource Sharing From a Server-Side Perspective (PHP, etc.)
- Cross-Origin Resource Sharing specification
XMLHttpRequest- Fetch API
- Using CORS with All (Modern) Browsers
- Using CORS - HTML5 Rocks
- Stack Overflow answer with "how to" info for dealing with common problems:
- How to avoid the CORS preflight
- How to use a CORS proxy to get around "No Access-Control-Allow-Origin header"
- How to fix "Access-Control-Allow-Origin header must not be the wildcard"