Как работает заголовок Access-Control-Allow-Origin?
видимо, я совершенно неправильно понял его слова. Я подумал о чем-то вроде этого:
- клиент загружает код javascript MyCode.js от http://siteA -источник.
- заголовок ответа MyCode.Яш содержит Access-Control-Allow-Origin: http://siteB, который я думал, что означает, что MyCode.js было разрешено делать перекрестные ссылки на сайт B.
- клиент запускает некоторые функции Mycode в.js, которые в свою очередь делают запросы к http://siteB, что должно быть хорошо, несмотря на то, что запросы кросс-происхождения.
Ну, я ошибаюсь. Это совсем не так работает. Итак, я прочитал Кросс-происхождения совместное использование ресурсов и попытался читать совместное использование ресурсов из разных источников в рекомендации w3c
одно точно - я до сих пор не понимаю, как я должен использовать этот заголовок.
У меня есть полный контроль сайт A и сайт B. Как включить код javascript, загруженный с сайта A, для доступа к ресурсам на сайте B с помощью этого заголовка?
П. С.
Я не хочу использовать JSONP.
11 ответов:
Access-Control-Allow-Origin
это CORS (Cross-Origin Resource Sharing) заголовок.когда сайт A пытается получить контент с сайта B, сайт B может отправить
Access-Control-Allow-Origin
заголовок ответа, чтобы сообщить браузеру, что содержимое этой страницы доступна в определенное происхождение. (Ан происхождения это домен, плюс схема и номер порта.) По умолчанию страницы сайта " В " составляет недоступно для любого другого источника; черезAccess-Control-Allow-Origin
заголовок открывает a дверь для перекрестного доступа происхождения специфическим запрашивая происхождением.для каждого ресурса/страницы, который Сайт B хочет сделать доступным для сайта A, сайт B должен обслуживать свои страницы с заголовком ответа:
Access-Control-Allow-Origin: http://siteA.com
современные браузеры не будут блокировать междоменные запросы напрямую. Если сайт A запрашивает страницу с сайта B, браузер фактически получит запрошенную страницу на сетевом уровне и проверьте, есть ли в заголовках ответов список сайта A как разрешенный домен отправителя. Если сайт B не указал, что сайту A разрешен доступ к этой странице, браузер запустит
XMLHttpRequest
' serror
событие и отклонить данные ответа на запрос кода JavaScript.не простые запросы
что происходит на сетевом уровне может быть немного сложнее, чем описано выше. Если запрос является "не простой" запрос, браузер сначала отправляет запрос параметров" предполетный " без данных, чтобы убедитесь, что сервер примет запрос. Запрос не является простым, когда либо (или оба):
- использование HTTP-глагола, отличного от GET или POST (например, PUT, DELETE)
- использование не простых заголовков запросов; единственными простыми заголовками запросов являются:
Accept
Accept-Language
Content-Language
Content-Type
(это просто только тогда, когда его значениеapplication/x-www-form-urlencoded
,multipart/form-data
, илиtext/plain
)если сервер отвечает на параметры preflight с соответствующими заголовками ответа (
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
добавляются браузером автоматически; вам не нужно добавлять их. Эта опция preflight получает успешные заголовки ответов: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 для получения дополнительной информации о непростых запросах.
Совместное Использование Запросов Кросс-Происхождения -
CORS
(A. K. A. Междоменный AJAX-запрос)-это проблема, с которой может столкнуться большинство веб-разработчиков, в соответствии с политикой того же происхождения браузеры ограничивают клиентский JavaScript в песочнице безопасности, обычно JS не может напрямую взаимодействовать с удаленным сервером из другого домена. В прошлом разработчики создали много сложных способов для достижения междоменного запроса ресурсов, чаще всего используя следующие способы:
- использование Flash/Silverlight или на стороне сервера как "прокси" для общения с пульта дистанционного управления.
- JSON с прокладкой (JSONP).
- встраивает удаленный сервер в iframe и связывается через фрагмент или window.name см.здесь.
эти хитрые способы имеют более или менее некоторые проблемы, например JSONP может привести к дыре в безопасности, если разработчики просто "eval" его, и #3 выше, хотя он работает, оба домена должны строить строгий контракт между собой, это ни гибкий и элегантный ИМХО:)
W3C ввела совместное использование ресурсов с перекрестным происхождением (CORS) в качестве стандартного решения для обеспечения безопасного, гибкого и рекомендуемого стандартного способа решения этой проблемы.
Механизм
С высокого уровня мы можем просто считать CORS-это контракт между клиентским AJAX-вызовом из домена A и страницей, размещенной на домене B, типичный запрос/ответ Кросс-происхождения будет:
DomainA AJAX запрос заголовки
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
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
синие части, отмеченные выше, были фактами ядра, заголовок запроса "Origin" указывает, откуда исходит запрос перекрестного происхождения или запрос перед полетом", заголовок ответа" Access-Control-Allow-Origin " указывает, что эта страница разрешает удаленный запрос из DomainA (если значение * указывает, что позволяет удаленные запросы из любого домена).
как я уже упоминал выше, W3 рекомендуется браузер для реализации "предварительный запрос " перед отправкой фактически перекрестного HTTP-запроса, в двух словах это HTTP
OPTIONS
запрос:OPTIONS DomainB.com/foo.aspx HTTP/1.1
если Foo.aspx поддерживает параметры HTTP verb, он может вернуть ответ, как показано ниже:
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" и его значение " * " или содержит домен, который отправил запрос CORS, выполнив это обязательное условие браузер будет отправьте фактический Междоменный запрос и кэшируйте результат в "Предварительный Результат-Кэш".
я писал о CORS три года назад: AJAX Cross-Origin HTTP request
вопрос слишком стар, чтобы ответить, но я публикую это для любой будущей ссылки на этот вопрос.
по данным этой Mozilla Developer Network article,
ресурс составляет перекрестный HTTP-запрос когда он запрашивает ресурс из другого домена или порта, чем тот, который обслуживает сам первый ресурс.
An HTML-страницы ежедневно с
http://domain-a.com
делает<img>
src запрос наhttp://domain-b.com/image.jpg
.
Многие страницы в интернете сегодня загружают ресурсы, такие как таблицы стилей CSS,изображения и скрипты из отдельных доменов (При этом должно быть прохладно).Политика Того Же Происхождения
по соображениям безопасности, браузеры ограничивают кросс-происхождение HTTP запросы запускать из скриптов.
Для например,XMLHttpRequest
иFetch
следуя политика того же происхождения.
Итак, веб-приложение с помощьюXMLHttpRequest
илиFetch
можно только сделать HTTP-запросов до свой собственный домен.совместное использование ресурсов из разных источников (CORS)
чтобы улучшить веб-приложения, разработчики попросили поставщиков браузеров разрешить междоменные запросы.
The совместное использование ресурсов из разных источников (CORS) механизм дает веб-сервера управление междоменным доступом, которые обеспечивают безопасную междоменную передачу данных.
Современные браузеры используют CORS на API container - например,XMLHttpRequest
илиFetch
- для снижения рисков перекрестных HTTP-запросов.как работает CORS ()
стандарт CORS описывает новые заголовки HTTP, которые предоставляют браузеры и серверы способ запроса удаленные URL-адреса только тогда, когда у них есть разрешение.
хотя некоторые проверки и авторизация могут быть выполнены сервером,это вообще ответственность браузера для поддержки этих заголовков и соблюдения ограничений, которые они налагают.
пример
браузер передает
OPTIONS
запрос .значение этого заголовка-это домен, который обслуживал родителя страница. Когда страница из
http://www.example.com
пытается получить доступ к данным пользователя вservice.example.com
следующий заголовок запроса будет направленservice.example.com
:происхождение:http://www.example.com
сервер
service.example.com
может реагировать с:
An
Access-Control-Allow-Origin
(ACAO) заголовок в своем ответе, указывающий, какие исходные сайты разрешены.
Например:
Access-Control-Allow-Origin: http://www.example.com
страница ошибки, если сервер не разрешает кросс-доменный запрос
An
Access-Control-Allow-Origin
(ACAO) заголовок с подстановочным знаком, который позволяет все домены:
Access-Control-Allow-Origin: *
Если вы хотите просто протестировать междоменное приложение, в котором браузер блокирует ваш запрос, то вы можете просто открыть браузер в небезопасном режиме и протестировать приложение без изменения кода и без создания небезопасного кода. Из MAC OS вы можете сделать это из терминальной линии:
open -a Google\ Chrome --args --disable-web-security --user-data-dir
используя реагировать и 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); }
1. Клиент загружает код javascript MyCode.js от http://siteA - происхождение.
код, который выполняет загрузку-ваш тег html-скрипта или xhr из javascript или что - то еще-пришел, скажем, http://siteZ. И, когда браузер запрашивает MyCode.js, он отправляет заголовок Origin: с надписью " Origin:http://siteZ", потому что он может видеть, что вы просите siteA и siteZ != siteA. (Вы не можете остановиться или вмешайтесь в это.)
2. Заголовок ответа MyCode.js содержит Access-Control-Allow-Origin:http://siteB, который я думал, что означает, что MyCode.js было разрешено делать перекрестные ссылки на сайт B.
нет. Это означает, что только siteB может сделать этот запрос. Так что ваш запрос на MyCode.вместо этого js из siteZ получает ошибку, и браузер обычно ничего не дает. Но если вы заставите ваш сервер вернуть A-C-A-O: siteZ вместо этого вы получите MyCode.js . Или если он пошлет '*', это сработает, это впустит всех. Или если сервер всегда отправляет строку из заголовка Origin:... но... для обеспечения безопасности, если вы боитесь хакеров, ваш сервер должен разрешать только origins в коротком списке, которым разрешено делать эти запросы.
Тогда, MyCode.js приходит от siteA. Когда он делает запросы к siteB, все они являются перекрестными, браузер отправляет Origin: siteA, и siteB должен принять siteA, распознать он находится в коротком списке разрешенных запросов и отправляет обратно A-C-A-O: siteA. Только тогда браузер позволит вашему скрипту получить результат этих запросов.
Я работаю с express 4 и node 7.4 и angular,у меня была та же проблема, что и у меня:
a) на стороне сервера: в приложении file.js я даю заголовки для всех ответов, таких как: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(); });
это должно быть прежде всего маршрутизатор.
Я видел много добавленных заголовков:res.header("Access-Control-Allow-Headers","*"); res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
но мне это не нужно,
b) на стороне клиента: в send ajax вам нужно добавить: "withCredentials: true", например:$http({ method: 'POST', url: 'url, withCredentials: true, data : {} }).then(function(response){ // code }, function (response) { // code });
удачи.
всякий раз, когда я начинаю думать о CORS, моя интуиция о том, на каком сайте размещены заголовки, неверна, как вы описали в своем вопросе. Для меня, это помогает думать о цели того же происхождения политики.
цель той же политики происхождения-защитить вас от вредоносного JavaScript на siteA.com доступ к личной информации, которую вы выбрали только для совместного использования siteB.com. без такой же политики происхождения, JavaScript написанный авторами siteA.com смог сделать Ваш браузер делает запросы к siteB.com, используя ваши аутентификационные куки для siteB.com таким образом, siteA.com может украсть секретную информацию, которой Вы делитесь siteA.com.
иногда вам нужно работать с кросс-доменом, в котором входит CORS. CORS ослабляет ту же политику происхождения для domainA.com, используя
Access-Control-Allow-Origin
заголовок для списка других доменов (domainB.com) которые доверяют запускать JavaScript, который может взаимодействовать с domainA.com.чтобы понять, какой домен следует подавайте заголовки CORS, подумайте об этом. Вы посещаете malicious.com, который содержит код JavaScript, который пытается сделать запрос домен крест mybank.com. Оно должно быть mybank.com не malicious.com, чтобы решить, будет ли или не он устанавливает CORS-заголовки, которые расслабляют ту же политику происхождения, позволяющих JavaScript из malicious.com для взаимодействия с ним. Если бы это было возможно malicous.com чтобы установить собственные заголовки CORS, разрешающие собственный доступ к JavaScript mybank.com, это полностью аннулирует же происхождения политики.
Я думаю, что причиной моей плохой интуиции является точка зрения, которую я имею при разработке сайта. Его мой сайт со всеми мой JavaScript, поэтому он не делает ничего вредоносного, и он должен быть до меня чтобы указать, какие другие сайты мой JavaScript может взаимодействовать. Когда на самом деле я должен думать, что другое сайты JavaScript пытаются взаимодействовать с моим сайтом и должны Я использую CORS, чтобы позволить им?
Если вы используете PHP, попробуйте добавить следующий код при отбрасывании файла php:
Если вы используете localhost, попробуйте следующее:
header("Access-Control-Allow-Origin: *");
Если вы используете внешние Домены, такие как сервер, попробуйте следующее:
header("Access-Control-Allow-Origin: http://www.website.com");
для совместного использования перекрестного источника установите заголовок:
'Access-Control-Allow-Origin':'*';
Php:
header('Access-Control-Allow-Origin':'*');
узел:
app.use('Access-Control-Allow-Origin':'*');
Это позволит обмениваться контентом для разных доменов.
в Python я использую
Flask-CORS
библиотека С большим успехом. Это делает работу с 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 в ионном приложении я здание, которое должно иметь доступ к отдельному серверу колб.