Nano Hash - криптовалюты, майнинг, программирование

Ошибка Access-Control-Allow-Origin, но запрос проходит

В настоящее время я развертываю базовый API на своем рабочем сервере и сталкиваюсь (как мне кажется) с проблемой CORS, но происходит какое-то поведение, которое я не могу объяснить.

Я общаюсь с интерфейсом AngularJS на Laravel 5 (+ laravel-cors) задний конец.

Я начал тестирование с простого вызова jQuery AJAX (ниже), и когда я делаю запрос из моей локальной среды Vagrant (http://dev.example.local/test.html) в http://api.example.com/v1/matches, я получаю сообщение об ошибке Access-Control-Allow-Origin. Странно то, что запрос действительно проходит, потому что информация хранится в базе данных через API на основе Laravel правильно.

$.ajax({
    method: 'POST',
    url: 'http://api.example.com/v1/players',
    data: {
        "username": "username",
        "first_name": "First",
        "last_name": "Last",
        "nickname": ""
    }
}).always(function(r) {
    console.log(r);
});

Ошибка:

XMLHttpRequest cannot load http://api.example.com/v1/players. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://other.example.com' is therefore not allowed access.

console.log(r) возвращает {readyState: 0, responseJSON: undefined, status: 0, statusText: "error"}

Я разработал приложение локально, используя виртуальную машину Homestead (API) и среду Vagrant (приложение), и оно работает правильно в этих средах...

Некоторые наблюдения:

  • Каждый из этих запросов отображается с методом: POST, статусом: 200 OK, типом: xhr в моих инструментах разработчика Chrome.
  • Такие инструменты, как Postman и тестер службы RESTful от PhpStorm, правильно выполняют запрос, и данные добавляются без ошибок.

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

01.09.2015

Ответы:


1

Ваш сервер должен вернуть соответствующий заголовок Access-Control-Allow-Origin в ответе. Например, если запрос отправляется с http://stackoverflow.com, ваш сервер должен вернуть этот заголовок: Access-Control-Allow-Origin: http://stackoverflow.com. Вы можете определить на стороне сервера, что является источником, просмотрев заголовок Origin в запросе. Если ваш сервер не возвращает этот заголовок в ответе, у вас не будет доступа к свойствам ответа на стороне браузера (таким как код состояния, заголовки или тело сообщения). В основе этого ограничения лежит Политика единого происхождения.

Причина, по которой вы не видите подобных проблем, когда запрос отправляется почтальоном или тестером службы RESTful PhpStorm, связана с тем, что эти службы не отправляют заголовок Origin с запросом, поскольку они не в соответствии с политикой единого происхождения. По умолчанию браузер будет добавлять этот заголовок к любым запросам ajax из разных источников, поскольку браузеры подпадают под действие единой политики происхождения. В моем предыдущем сценарии заголовок запроса выглядел бы так: Origin: http://stackoverflow.com. Браузеры, реализующие спецификацию CORS, должны добавлять этот заголовок запроса, чтобы сервер мог определить, является ли источником запрос был внесен в белый список для запросов ajax из разных источников. В этом случае сервер вернет правильный заголовок Access-Control-Allow-Origin. Если нет, он может просто опустить заголовок. Браузеры, которые не реализуют спецификацию CORS, просто откажутся отправлять такой запрос ajax.

Что касается вашего недоумения по поводу того, почему запрос отправляется в первую очередь, это сводится к различию между «простыми» и «непростыми» запросами CORS. Для простых запросов CORS запрос будет всегда отправляться на сервер, но клиент/JS не сможет проанализировать ответ без надлежащего подтверждения от сервера. Некоторые запросы CORS, так сказать, непросты. Это, например, запросы DELETE или PATCH или запросы POST/GET, которые содержат нестандартные заголовки (например, X-заголовки или Content-Type из «application/json» вместо «multipart/form-data»). Другими словами, запрос непрост, если его нельзя отправить без JavaScript. Например, отправка <form> или запрос GET от <script src="..."> всегда будут отправлять «простые» запросы. Для непростых запросов браузер должен выполнить предварительную проверку запроса. Это означает, что браузер отправляет промежуточный запрос, называемый предварительным, перед исходным запросом. Этот предварительный запрос является запросом OPTIONS. Затем сервер должен возвращать заголовки в ответ на эту предварительную проверку, подтверждающие любые нестандартные свойства исходного запроса. Если да, то браузер отправит исходный запрос.

Подробнее о предварительной проверке и CORS в целом можно прочитать на MDN.

02.09.2015
  • Я уже знал большую часть того, что вы сказали, но объяснение того, почему запрос будет выполнен, было для меня новым, спасибо! Я на 99% уверен, что в серверной части Access-Control-Allow-Origin установлено значение *, поскольку это общедоступный API, есть ли способ проверить это? И поскольку я запускаю запросы AJAX POST через jQuery, они непросты, верно? Поэтому они должны отправить предварительный запрос. Должен ли я видеть это на вкладке «Сеть» инструментов разработки Chrome, поскольку я их не вижу. 02.09.2015
  • Оказывается, я неправильно реализовал пакет laravel-cors или что-то в этом роде. Я добавил заголовок Access-Control-Allow-Origin к моему виртуальному хосту apache2, и теперь он работает правильно... 02.09.2015
  • Если браузер не отправляет предварительную проверку, то запросы простые. Не имеет значения, отправляете ли вы их с помощью jQuery или нет. Запросы непросты только в том случае, если они содержат некоторые из вещей, которые я упомянул в своем ответе. Например, если вы установите тип содержимого запроса, отправляемого jQuery, на application/json, браузер выполнит предварительную проверку запроса. Статья MDN, на которую я ссылался, более подробно описана. 02.09.2015
  • В вашем вопросе не было очевидно, что вы поняли, что такое CORS, или что вы уже пытались вернуть правильный заголовок CORS. Теперь я вижу, что вы упомянули laraval-cors. 02.09.2015
  • Совершенно никаких проблем. Спасибо за подробное объяснение, это, безусловно, освежило мою память о CORS. И в итоге я еще немного протестировал его благодаря вашему ответу, поэтому я отмечу его как принятый. 03.09.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..