При попытке получить данные из REST API на запрашиваемом ресурсе отсутствует заголовок 'Access-Control-Allow-Origin'.
Я'пытаюсь получить некоторые данные из REST API HP Alm. Это работает довольно хорошо с небольшим скриптом curl - я получаю свои данные.
А вот с JavaScript, fetch и ES6 (более или менее), похоже, проблема посерьезнее. Я продолжаю получать это сообщение об ошибке:
Fetch API не может загрузить . Ответ на запрос preflight не проходит прошел проверку контроля доступа: No 'Access-Control-Allow-Origin' header is присутствует на запрашиваемом ресурсе. Origin 'http://127.0.0.1:3000' является поэтому доступ к нему запрещен. Ответ имеет код состояния HTTP 501. Если непрозрачный ответ отвечает вашим потребностям, установите для запроса > 'режим>. 'no-cors', чтобы получить ресурс с отключенным CORS.
Я понимаю, что это происходит потому, что я пытаюсь получить эти данные с моего локального хоста, и решение должно заключаться в использовании CORS. Теперь я подумал, что я действительно сделал это, но каким-то образом он либо игнорирует то, что я пишу в заголовке, либо проблема заключается в чем-то другом?
Итак, есть ли проблема с реализацией? Я делаю это неправильно? К сожалению, я не могу проверить журналы сервера. Я действительно немного застрял здесь.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Я использую Chrome. Я также попытался использовать этот Chrome CORS Plugin, но тогда я получаю другое сообщение об ошибке:
Значение заголовка 'Access-Control-Allow-Origin' в ответе не должно быть подстановочным символом '*', когда запрос'credentials mode is 'include'. Таким образом, Origin 'http://127.0.0.1:3000' не имеет права доступ. Режим учетных данных для запросов, инициированных функцией XMLHttpRequest, контролируется атрибутом withCredentials.
Этот ответ охватывает много тем, поэтому он разделен на три части:
Как решить проблемы с "Заголовок Access-Control-Allow-Origin не должен быть подстановочным символом "
Как использовать CORS-прокси, чтобы обойти "Нет заголовка Access-Control-Allow-Origin " проблемы. Если вы не контролируете сервер, на который ваш внешний JavaScript-код отправляет запрос, и проблема с ответом от этого сервера заключается только в отсутствии необходимого заголовка
Access-Control-Allow-Origin
, вы все равно можете заставить его работать, выполнив запрос через CORS-прокси. Чтобы показать, как это работает, сначала приведем код, который не использует CORS-прокси:Причина, по которой блок
catch
попадает туда, заключается в том, что браузер не позволяет этому коду получить доступ к ответу, который возвращается сhttps://example.com
. Причина, по которой браузер это делает, заключается в том, что в ответе отсутствует заголовок ответаAccess-Control-Allow-Origin
. А вот точно такой же пример, но только с добавлением CORS-прокси:Примечание: Если https://cors-anywhere.herokuapp.com не работает или недоступен, то смотрите ниже, как развернуть свой собственный CORS Anywhere сервер на Heroku всего за 2-3 минуты. Второй фрагмент кода выше может успешно получить доступ к ответу, потому что если взять URL запроса и изменить его на https://cors-anywhere.herokuapp.com/https://example.com-by, просто префиксировав его с URL прокси, то запрос будет сделан через этот прокси, который затем:
https://example.com
.https://example.com
.Access-Control-Allow-Origin
к ответу.Access-Control-Allow-Origin
видит браузер. Вы можете легко запустить свой собственный прокси, используя код с сайта https://github.com/Rob--W/cors-anywhere/.Вы также можете легко развернуть свой собственный прокси на Heroku буквально за 2-3 минуты, выполнив 5 команд:
Выполнив эти команды, вы получите собственный сервер CORS Anywhere, работающий, например, по адресу https://cryptic-headland-94862.herokuapp.com/. Тогда вместо префикса
https://cors-anywhere.herokuapp.com
в URL-адресе вашего запроса вместо него будет указан URL-адрес вашего собственного экземпляра; например, https://cryptic-headland-94862.herokuapp.com/https://example.com. Если вы попытаетесь использовать https://cors-anywhere.herokuapp.com и обнаружите, что он не работает (а иногда так и бывает), то заведите аккаунт на Heroku (если у вас его еще нет) и потратьте 2-3 минуты на выполнение описанных выше действий, чтобы развернуть собственный сервер CORS Anywhere на Heroku. Независимо от того, используете ли вы свой собственный или https://cors-anywhere.herokuapp.com или другой открытый прокси, это решение будет работать, даже если запрос будет таким, который заставляет браузеры делать предварительный CORS-запросOPTIONS
- потому что в этом случае прокси также отправляет обратно заголовкиAccess-Control-Allow-Headers
иAccess-Control-Allow-Methods
, необходимые для успешной предварительной проверки.Как избежать предварительной проверки CORS. Код в вопросе вызывает предварительную проверку CORS, поскольку отправляет заголовок
Authorization
. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests Даже без этого, заголовокContent-Type: application/json
также вызовет префлайт. Что означает "preflight": прежде чем браузер попробует выполнитьPOST
в коде из вопроса, он сначала отправит серверу запросOPTIONS
- чтобы определить, согласен ли сервер на получение кросс-оригинальногоPOST
, включающего заголовкиAuthorization
иContent-Type: application/json
....с
https://the.sign_in.url
, замененным на ваш фактический URLsign_in
. Ответ, который браузер должен получить от этого запросаOPTIONS
, должен содержать такие заголовки, как:Если ответ
OPTIONS
не содержит этих заголовков, то браузер остановится на этом и даже не попытается отправить запросPOST
. Кроме того, код состояния HTTP для ответа должен быть 2xx - обычно 200 или 204. Если это любой другой код статуса, браузер остановится прямо на месте. Сервер, о котором идет речь, отвечает на запросOPTIONS
кодом состояния 501, что, очевидно, означает, что он пытается указать на отсутствие поддержки запросовOPTIONS
. Другие серверы в этом случае обычно отвечают кодом состояния 405 "Метод не разрешен". Таким образом, вы никогда не сможете делатьPOST
-запросы непосредственно к этому серверу из вашего внешнего JavaScript-кода, если сервер ответит на этотOPTIONS
-запрос кодом 405 или 501, или чем-либо другим, кроме 200 или 204, или если он не ответит необходимыми заголовками ответа. Способ избежать срабатывания префлайта для случая, о котором идет речь в вопросе, следующий:Authorization
, а вместо этого (например) полагается на данные аутентификации, встроенные в тело запросаPOST
или в качестве параметра запросаесли сервер не требовал, чтобы тело
POST
имело медиа-типContent-Type: application/json
, а вместо этого принял телоPOST
какapplication/x-www-form-urlencoded
с параметромjson
(или любым другим), значением которого являются данные JSON.Как решить проблему "Заголовок Access-Control-Allow-Origin не должен быть подстановочным символом ".
Но это только один пример; другие (веб-) серверные системы предоставляют аналогичные способы передачи значений происхождения.
Удалите эти строки. Заголовки
Access-Control-Allow-*
являются заголовками ответа. Вы никогда не захотите отправлять их в запросе. Единственное, на что это может повлиять, - заставить браузер выполнить предварительную проверку.Эта ошибка возникает, когда URL клиента и URL сервера не совпадают, включая номер порта. В этом случае вам необходимо включить в вашем сервисе функцию CORS - кросс-оригинальный обмен ресурсами.
Если вы используете REST-сервис Spring, то вы можете найти это в блоге Поддержка CORS в Spring Framework.
Если вы размещаете сервис на сервере Node.js, то
Остановите сервер Node.js.
npm install cors --save
.Добавьте следующие строки в файл server.js
var cors = require('cors')
app.use(cors()) // Используйте это после объявления переменной
Проблема возникла из-за того, что вы добавили следующий код в виде заголовка request в интерфейсе:
Эти заголовки принадлежат ответу , а не запросу. Так что удалите их, включая строку: < br / >
Ваш запрос имел «Content-Type: application / json», следовательно, вызвал то, что называется предполетным CORS. Это вызвало то, что браузер отправил запрос с методом OPTIONS. См. CORS preflight для получения подробной информации. & Лт; br / > Поэтому в вашем бэк-энде вы должны обработать этот предварительно выполненный запрос, вернув заголовки ответов, которые включают:
Конечно, фактический синтаксис зависит от языка программирования, который вы используете для своего бэкэнда.
В вашем интерфейсе это должно быть так:
В моем случае я использую решение ниже
Front-end или Angular
бэкэнд (я использую php)
Просто мои два цента... относительно Как использовать прокси-сервер CORS, чтобы обойти проблемы «Нет заголовка« Access-Control-Allow-Origin »
Для тех из вас, кто работает с php на бэкэнде, развертывание «прокси-сервера CORS» так же просто, как:
создать файл с именем 'no-cors.php' со следующим содержимым:
$ URL = $ _GET ['url'] ; echo json_encode (file_get_contents ($ URL)) ; умереть();
на переднем конце сделайте что-нибудь вроде:
fetch ('https://example.com/no-cors.php' + '?url = '+ url) .then (response = > {* / Handle Response / *})
Уберите это:
В моем случае веб-сервер предотвратил метод «ОПЦИИ»
Проверьте свой веб-сервер на предмет параметров метода
перейти на
Я получал эту ошибку на моем местном. Я запустил Visual Studio в качестве администратора, и это решено.
Использование
dataType: 'jsonp'
работало для меня.Я работал с Spring REST и решил добавить «Разрешенные методы» в WebMvcConfigurer.
Самое быстрое исправление, которое вы можете сделать, - это установить расширение Moesif CORS .
После установки щелкните его в браузере, чтобы активировать расширение. Убедитесь, что метка значка идет от «выкл»
«вкл» ;
Затем обновите ваше приложение, и ваши запросы API теперь должны работать!
Плагин определенно решает проблему. Однако это исправление относится только к вашей машине. В локальном развитии хорошо установить плагин, который поможет вам преодолеть ошибку.