В запрошенном ресурсе нет заголовка "Access-Control-Allow-Origin" - при попытке получить данные из REST API
Я пытаюсь получить некоторые данные из REST API HP Alm. Он работает очень хорошо с небольшим завитком script - я получаю свои данные.
Теперь, используя JavaScript, выборка и ES6 (более или менее) кажутся более серьезной проблемой. Я продолжаю получать это сообщение об ошибке:
API-интерфейс Fetch не может загружаться. Ответ на предполетный запрос не проверка контроля доступа: нет заголовка "Access-Control-Allow-Origin" присутствовать на запрошенном ресурсе. Origin 'http://127.0.0.1:3000' является поэтому не допускается доступ. В ответе был код статуса 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, но потом я получаю еще одно сообщение об ошибке:
Значение заголовка "Access-Control-Allow-Origin" в ответе не должен быть подстановочным знаком '*', когда режим учетных данных запроса 'включают'. Origin 'http://127.0.0.1:3000' поэтому не допускается доступ. Режим учетных данных запросов, инициированных XMLHttpRequest контролируется атрибутом withCredentials.
Ответы
Ответ 1
Этот ответ охватывает много вопросов, поэтому он разделен на три части:
- Как использовать прокси-сервер CORS для решения проблемы "Нет заголовка Access-Control-Allow-Origin"
- Как избежать предполетной проверки CORS
- Как исправить проблему "заголовок Access-Control-Allow-Origin не должен быть подстановочным знаком"
Как использовать прокси-сервер CORS для решения проблемы "Нет заголовка Access-Control-Allow-Origin"
Если вы не контролируете сервер, на который отправляет запрос ваш код JavaScript, и проблема с ответом с этого сервера заключается просто в отсутствии необходимого заголовка Access-Control-Allow-Origin
, вы все равно можете заставить вещи работать: сделать запрос через прокси-сервер CORS. Чтобы показать, как это работает, сначала рассмотрим код, который не использует прокси-сервер CORS:
const url = "https://example.com"; // site that doesnt send Access-Control-*
fetch(url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Cant access " + url + " response. Blocked by browser?"))
Ответ 2
Эта ошибка возникает, когда URL-адрес клиента и URL-адрес сервера не совпадают, включая номер порта. В этом случае вам необходимо включить службу для CORS, которая является совместным использованием ресурсов из разных источников.
Если у вас есть служба Spring REST, вы можете найти ее в блоге поддержки CORS в Spring Framework.
Если вы размещаете сервис на сервере Node.js, то
- Остановите сервер Node.js.
-
npm install cors --save
-
Добавьте следующие строки в ваш server.js
var cors = require('cors')
app.use(cors()) // Use this after the variable declaration
Ответ 3
Проблема возникла потому, что вы добавили следующий код в качестве заголовка запроса в ваш интерфейс:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Эти заголовки принадлежат ответу, а не запросу. Поэтому удалите их, включая строку:
headers.append('GET', 'POST', 'OPTIONS');
Ваш запрос содержал "Content-Type: application/json", следовательно, вызвал то, что называется предварительным просмотром CORS. Это привело к тому, что браузер отправил запрос методом OPTIONS. Смотрите предварительную проверку CORS для получения подробной информации.
Поэтому в вашем бэкэнде вы должны обработать этот предварительно выданный запрос, возвращая заголовки ответа, которые включают:
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept
Конечно, фактический синтаксис зависит от языка программирования, который вы используете для своей серверной части.
В вашем интерфейсе это должно быть так:
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
headers.append('Origin','http://localhost:3000');
fetch(sign_in, {
mode: 'cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Ответ 4
Удали это:
credentials: 'include',
Ответ 5
Использование dataType: 'jsonp'
работал для меня.
async function get_ajax_data(){
var _reprojected_lat_lng = await $.ajax({
type: 'GET',
dataType: 'jsonp',
data: {},
url: _reprojection_url,
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
console.log(data);
// note: data is already json type, you
// just specify dataType: jsonp
return data;
}
});
} // function
Ответ 6
Я работал с Spring REST и решил, добавив AllowedMethods в WebMvcConfigurer.
@Value( "${app.allow.origins}" )
private String allowOrigins;
@Bean
public WebMvcConfigurer corsConfigurer() {
System.out.println("allow origin: "+allowOrigins);
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//.allowedOrigins("http://localhost")
.allowedOrigins(allowOrigins)
.allowedMethods("PUT", "DELETE","GET", "POST");
}
};
}
Ответ 7
Только мои два цента... относительно того, как использовать прокси-сервер CORS, чтобы обойти проблемы "Нет заголовка Access-Control-Allow-Origin
"
Для тех из вас, кто работает с php на сервере, развертывание "прокси-сервера CORS" так же просто, как:
-
создайте файл с именем "no-cors.php" со следующим содержимым:
$URL = $_GET['url']; echo json_encode(file_get_contents($URL)); die();
-
на вашем интерфейсе сделайте что-то вроде:
fetch('https://example.com/no-cors.php' + '?url=' + url).then(response=>{*/Handle Response/*})
Ответ 8
В моем случае веб-сервер запретил метод "ОПЦИИ"
Проверьте свой веб-сервер на наличие метода опций
I'm using "webtier"
/www/webtier/domains/[domainname]/config/fmwconfig/components/OHS/VCWeb1/httpd.conf
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteRule .* . [F]
</IfModule>
изменить на
<IfModule mod_rewrite.c>
RewriteEngine off
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteRule .* . [F]
</IfModule>
Ответ 9
В моем случае я использую приведенное ниже решение
Передний или angular
post(
this.serverUrl, dataObjToPost,
{
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
)
серверная часть (я использую php)
header("Access-Control-Allow-Origin: http://localhost:4200");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
print_r($request);
Ответ 10
Я получал эту ошибку на моем местном.
Я запустил Visual Studio в качестве администратора, и это решило.