Вопрос по javascript – Как работает заголовок Access-Control-Allow-Origin?

907

Видимо, я совершенно не понял ее семантику. Я думал о чем-то вроде этого:

A client downloads javascript code MyCode.js from http://siteA - the origin. The response header of MyCode.js contains Access-Control-Allow-Origin: http://siteB, which I thought meant that MyCode.js was allowed to make cross-origin references to the site B. The client triggers some functionality of MyCode.js, which in turn make requests to http://siteB, which should be fine, despite being cross-origin requests.

Ну, я не прав. Это не работает, как это вообще. Итак, я прочиталСовместное использование ресурсов и попытался прочитатьСовместное использование ресурсов в рекомендациях w3c

Одно можно сказать наверняка - я все еще не понимаю, как я должен использовать этот заголовок.

У меня есть полный контроль над сайтом A и сайтом B. Как включить код JavaScript, загруженный с сайта A, для доступа к ресурсам на сайте B с помощью этого заголовка?

Постскриптум

Я не хочу использовать JSONP.

@mark Вам не нужно загружать ресурс, чтобы получить заголовки. Метод HTTP HEADER возвращает только заголовки. А в случае CORS проверка перед полетом выполняется с использованием метода HTTP OPTIONS, который также не возвращает тело. ответ апсиллеров это красиво описываетstackoverflow.com/posts/10636765/revisions. Matt
Я не уверен, но полагаю, что установка заголовка таким образом позволяет загружать код на сайте Bhttp://siteA/MyCode.js. pimvdb
Но как??? Чтобы получить значение заголовка, нужно сначала извлечь ресурс, но ресурс является перекрестным источником, и поэтому браузер не должен блокировать запрос в первую очередь? mark
То, что вы описали, на самом деле напоминает другую практику,Content Security Policy Alex

Ваш Ответ

13   ответов
43

чтобы ответить, но я публикую его для любой будущей ссылки на этот вопрос.

В соответствии сэтот Статья Mozilla Developer Network,

A resource makes a cross-origin HTTP request when it requests a resource from a different domain, or port than the one which the first resource itself serves.

enter image description here

HTML page подается изhttp://domain-a.com делает<img> запрос SRC дляhttp://domain-b.com/image.jpg.
Многие страницы в Интернете сегодня загружают такие ресурсы, какCSS stylesheets, images а такжеscripts из отдельных доменов (при этом должно быть круто).

Same-Origin Policy

Из соображений безопасности браузеры ограничиваютcross-origin HTTP Запросыinitiated from within scripts.
Например,XMLHttpRequest а такжеFetch следоватьsame-origin policy.
Итак, веб-приложение, использующееXMLHttpRequest или жеFetch мог только сделатьHTTP requests вits own domain.

Cross-Origin Resource Sharing (CORS)

Чтобы улучшить веб-приложения, разработчики попросили поставщиков браузеров разрешить междоменные запросы.

Cross-Origin Resource Sharing (CORS) механизм дает веб-серверыcross-domain access controls, которые обеспечивают безопасную междоменную передачу данных.
Современные браузеры используютCORS вAPI container - такие какXMLHttpRequest или жеFetch - снизить риски перекрестных HTTP-запросов.

How CORS works (Access-Control-Allow-Origin header)

Википедия:

The CORS standard describes new HTTP headers which provide browsers and servers a way to request remote URLs only when they have permission.

Although some validation and authorization can be performed by the server, it is generally the browser's responsibility to support these headers and honor the restrictions they impose.

Example

The browser sends the OPTIONS request with an Origin HTTP header.

The value of this header is the domain that served the parent page. When a page from http://www.example.com attempts to access a user's data in service.example.com, the following request header would be sent to service.example.com:

Origin: http://www.example.com

The server at service.example.com may respond with:

An Access-Control-Allow-Origin (ACAO) header in its response indicating which origin sites are allowed.
For example:

Access-Control-Allow-Origin: http://www.example.com

An error page if the server does not allow the cross-origin request

An Access-Control-Allow-Origin (ACAO) header with a wildcard that allows all domains:

Access-Control-Allow-Origin: *

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededAccess-Control-Allow-Origin:null
Error: User Rate Limit ExceededAccess-Control-Allow-OriginError: User Rate Limit ExceededAccess-Control-Allow-Origin: *
8

в котором браузер блокирует ваш запрос, вы можете просто открыть свой браузер в небезопасном режиме и протестировать свое приложение, не изменяя код и не делая ваш код небезопасным. Из MAC OS вы можете сделать это из терминальной линии:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
7

когда я начинаю думать о CORS, моя интуиция о том, какой сайт размещает заголовки, неверна, как вы описали в своем вопросе. Для меня это помогает думать о цели той же политики происхождения.

Цель той же политики происхождения заключается в защите вас от вредоносного JavaScript на siteA.com, получающего доступ к частной информации, которую вы выбрали для обмена только с siteB.com. Без такой же политики происхождения JavaScript, написанный авторами siteA.com, может заставить ваш браузер отправлять запросы на siteB.com, используя ваши файлы cookie для аутентификации для siteB.com. Таким образом, siteA.com может украсть секретную информацию, которой вы делитесь с siteB.com.

Иногда вам нужно работать с кросс-доменом, в который входит CORS. CORS ослабляет ту же политику происхождения для domainA.com, используяAccess-Control-Allow-Origin заголовок списка других доменов (domainB.com), которым доверяют запускать JavaScript, который может взаимодействовать с domainA.com.

Чтобы понять, какой домен должен обслуживать заголовки CORS, подумайте об этом. Вы посещаете malware.com, который содержит некоторый JavaScript, который пытается сделать кросс-доменный запрос к mybank.com. Решение о том, устанавливает ли он заголовки CORS, ослабляют ли ту же политику происхождения, позволяющую JavaScript с вредоносного сайта взаимодействовать с ним, должен решать mybank.com, а не malware.com. Если бы malicous.com мог установить собственные заголовки CORS, разрешающие собственный доступ JavaScript к mybank.com, это полностью аннулировало бы ту же политику происхождения.

Я думаю, что причиной моей плохой интуиции является точка зрения, которую я имею при разработке сайта. Это & APOS; smy сайт, со всемиmy JavaScript, поэтому он не делает ничего вредоносного и должен быть доme указать, какие другие сайтыmy JavaScript может взаимодействовать с. Когда на самом деле я должен думать, которыйother сайты JavaScript пытается взаимодействовать с моим сайтом и должен ли я использовать CORS, чтобы разрешить их?

6

у меня была та же проблема, мне помочь это:
a) server side: in file app.js i give headers to all response like:

app.use(function(req, res, next) {  
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
 });  

this must have before all router.
Я видел много добавленных заголовков:

res.header("Access-Control-Allow-Headers","*");
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');

но мне это не нужно,
б) на стороне клиента: при отправке ajax необходимо добавить: & with; credentials: true, & quot; лайк:

$http({
     method: 'POST',
     url: 'url, 
     withCredentials: true,
     data : {}
   }).then(function(response){
        // code  
   }, function (response) {
         // code 
   });

удачи.

0

response can be shared with requesting code from the given origin.

Header type Response       header
Forbidden header name      no

A response that tells the browser to allow code from any origin to access a resource will include the following:

Access-Control-Allow-Origin: *

Для получения дополнительной информации посетитеВот....

2

Flask-CORS library с большим успехом. Это делает работу с CORS супер простой и безболезненной. Я добавил некоторый код из документации библиотеки ниже.

Установка:

$ pip install -U flask-cors

Простой пример, который позволяет CORS для всех доменов на всех маршрутах:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

Для более конкретных примеров см. Документацию. Я использовал простой пример, описанный выше, чтобы обойти проблему CORS в создаваемом ионном приложении, которое должно получить доступ к отдельному серверу-колбе.

3

попробуйте добавить следующий код в beaning файла php:

если вы используете localhost, попробуйте это:

header("Access-Control-Allow-Origin: *");

если вы используете внешние домены, такие как сервер, попробуйте это:

header("Access-Control-Allow-Origin: http://www.website.com");
6

1. A client downloads javascript code MyCode.js from Http: // SiteA - Происхождение.

Код, который выполняет загрузку - ваш тег html-сценария или xhr из javascript или чего-либо еще - пришел, скажем,Http: // siteZ, И когда браузер запрашивает MyCode.js, он отправляет заголовок Origin: с заголовком «Origin:Http: // siteZ& quot ;, поскольку он может видеть, что вы запрашиваете данные на siteA и siteZ! = siteA. (Вы не можете остановиться или помешать этому.)

2. The response header of MyCode.js contains Access-Control-Allow-Origin: Http: // SITEBЯ думал, что это означает, что MyCode.js было разрешено делать ссылки на источник B.

нет. Это означает, что только siteB разрешено делать этот запрос. Таким образом, ваш запрос MyCode.js от siteZ вместо этого получает ошибку, и браузер обычно ничего не дает. Но если вместо этого вы заставите свой сервер возвращать A-C-A-O: siteZ, вы получите MyCode.js. Или, если он отправит «*», который «сработает», он впустит всех. Или если сервер всегда отправит строку из заголовка Origin: ... но ... в целях безопасности, если вы боитесь из хакеров, ваш сервер должен разрешать только источники в шорт-листе, которым разрешено делать эти запросы.

Затем MyCode.js приходит с сайта A. Когда он отправляет запросы на сайт B, все они имеют перекрестное происхождение, браузер отправляет Origin: siteA, и siteB должен взять сайт A, распознать его в коротком списке разрешенных запросчиков и отправить обратно A-C-A-O: siteA. Только тогда браузер позволит вашему сценарию получить результат этих запросов.

8

React а такжеAxiosприсоедините прокси-ссылку к URL и добавьте заголовок, как показано ниже

https://cors-anywhere.herokuapp.com/ + Your API URL

Просто добавив ссылку «Прокси», вы сможете снова получить сообщение об отсутствии доступа. Следовательно, лучше добавить заголовок, как показано ниже.

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
107

CORS (A.K.A. Междоменный запрос AJAX) - это проблема, с которой может столкнуться большинство веб-разработчиков. Согласно Same-Origin-Policy, браузеры ограничивают клиентский JavaScript в изолированной программной среде безопасности, обычно JS не может напрямую взаимодействовать с удаленным сервером из другого домена. В прошлом разработчики создавали множество хитрых способов добиться запроса к междоменному ресурсу, чаще всего с использованием следующих способов:

Use Flash/Silverlight or server side as a "proxy" to communicate with remote. JSON With Padding (JSONP). Embeds remote server in an iframe and communicate through fragment or window.name, refer here.

У этих хитрых способов есть более или менее некоторые проблемы, например, JSONP может привести к дыре в безопасности, если разработчики просто "eval" это и # 3 выше, хотя и работает, оба домена должны строить строгие контракты между собой, это ни гибко, ни элегантно ИМХО :)

W3C представила Cross-Origin Resource Sharing (CORS) в качестве стандартного решения, чтобы обеспечить безопасный, гибкий и рекомендуемый стандартный способ решения этой проблемы.

The Mechanism

На высоком уровне мы можем просто считать, что CORS - это контракт между клиентским вызовом AJAX из домена A и страницей, размещенной в домене B, типичный запрос / ответ Cross-Origin будет выглядеть так:

DomainA AJAX request headers

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

DomainB response headers

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

Синие части, которые я отмечал выше, были основными фактами, «Происхождение». Заголовок запроса "указывает, откуда исходят запрос на перекрестный источник или запрос на предварительную проверку от", Access-Control-Allow-Origin ". заголовок ответа указывает, что эта страница разрешает удаленный запрос от DomainA (если значение * указывает, разрешает удаленные запросы из любого домена).

Как я упоминал выше, W3 рекомендовал браузер для реализации & quot;preflight request& Quot; перед отправкой фактически HTTP-запроса Cross-Origin, в двух словах это HTTPOPTIONS запрос:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

Если foo.aspx поддерживает HTTP-глагол OPTIONS, он может вернуть ответ, как показано ниже:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

Только если ответ содержит «Access-Control-Allow-Origin» И его значение равно & quot; * & quot; или содержать домен, который отправил запрос CORS, выполнив это обязательное условие, браузер отправит фактический междоменный запрос и сохранит результат в & quot;Preflight-Result-Cache& Quot ;.

Я писал о CORS три года назад:HTTP-запрос AJAX Cross-Origin

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

'Access-Control-Allow-Origin':'*';

Php:header('Access-Control-Allow-Origin':'*');

Узел:app.use('Access-Control-Allow-Origin':'*');

Это позволит обмениваться контентом для другого домена.

0

Отметил, что вы должны вставить следующий код в<system.webServer> тег

    <httpProtocol>  
    <customHeaders>  
     <add name="Access-Control-Allow-Origin" value="*" />  
     <add name="Access-Control-Allow-Headers" value="Content-Type" />  
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />  
    </customHeaders>  
  </httpProtocol>  
1162

Access-Control-Allow-Origin этоЗаголовок CORS (Cross-Origin Resource Sharing).

Когда сайт A пытается извлечь контент с сайта B, сайт B может отправитьAccess-Control-Allow-Origin заголовок ответа, чтобы сообщить браузеру, что содержимое этой страницы доступно для определенных источников. (Anorigin этодомен, плюс схема и номер порта.) По умолчанию страницы сайта Bнедоступен для любого другого происхождения; с использованиемAccess-Control-Allow-Origin заголовок открывает дверь для перекрестного доступа по конкретным запрашивающим источникам.

Для каждого ресурса / страницы, которые Сайт B хочет сделать доступными для Сайта A, Сайт B должен обслуживать свои страницы с заголовком ответа:

Access-Control-Allow-Origin: http://siteA.com

Современные браузеры не будут блокировать междоменные запросы напрямую. Если сайт A запрашивает страницу с сайта B, браузер фактически получает запрашиваемую страницуon the network level и проверьте, содержит ли заголовки ответа сайт A в качестве разрешенного домена запрашивающей стороны. Если сайт B не указал, что сайту A разрешен доступ к этой странице, браузер вызоветXMLHttpRequest& APOS; serror событие и запретить данные ответа запрашивающему коду JavaScript.

Non-simple requests

То, что происходит на уровне сети, может бытьslightly более сложный, чем объяснено выше. Если запрос& Quot; непростая & Quot; запросбраузер сначала отправляет «preflight» без предварительной обработки данных ОПЦИИ запроса, чтобы убедиться, что сервер примет запрос. Запрос является непростым, когда либо (или оба):

using an HTTP verb other than GET or POST (e.g. PUT, DELETE) using non-simple request headers; the only simple requests headers are: Accept Accept-Language Content-Language Content-Type (this is only simple when its value is application/x-www-form-urlencoded, multipart/form-data, or text/plain)

Если сервер отвечает на предварительный просмотр OPTIONS с соответствующими заголовками ответа (Access-Control-Allow-Headers для непростых заголовков,Access-Control-Allow-Methods для непростых глаголов), которые соответствуют непростым глаголам и / или непростым заголовкам, тогда браузер отправляет фактический запрос.

Предположим, что Сайт A хочет отправить запрос PUT для/somePageс непростымContent-Type ценностьapplication/jsonбраузер сначала отправит предварительный запрос:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Обратите внимание, чтоAccess-Control-Request-Method а такжеAccess-Control-Request-Headers добавляются браузером автоматически; Вам не нужно добавлять их. Этот предварительный просмотр OPTIONS получает заголовки успешного ответа:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

При отправке фактического запроса (после выполнения предварительной проверки) поведение идентично тому, как обрабатывается простой запрос. Другими словами, непростой запрос, предпечатная проверка которого успешна, обрабатывается так же, как и простой запрос (т. Е. Сервер все еще должен отправитьAccess-Control-Allow-Origin снова за фактический ответ).

Браузеры отправляют актуальный запрос:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

И сервер отправляет обратноAccess-Control-Allow-Originтак же, как и для простого запроса:

Access-Control-Allow-Origin: http://siteA.com

УвидетьПонимание XMLHttpRequest через CORS немного больше информации о непростых запросах.

Error: User Rate Limit ExceededAccess-Control-Allow-OriginError: User Rate Limit Exceeded*Error: User Rate Limit ExceededOriginError: User Rate Limit Exceeded
Error: User Rate Limit ExceededAccess-Control-Allow-OriginError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded mark
Error: User Rate Limit Exceededwhy?Error: User Rate Limit ExceededyouError: User Rate Limit Exceededprogrammers.stackexchange.com/q/216605Error: User Rate Limit ExceededWhat is the threat model for the same origin policy?
Error: User Rate Limit Exceeded mark

Похожие вопросы