CORS: PHP: ответ на запрос preflight не проходит. Я позволяя происхождения
поэтому я знаю, что там много сообщений CORS, и я просто добавляю к ним, но я не могу найти ответов, которые помогут мне. Поэтому я создаю приложение angular 4, которое опирается на мой php api. Работая локально, это нормально, в тот момент, когда я бросаю его на домен с приложением в app.example.com
, и api в api.example.com
, Я не могу пройти мой логин, потому что я получаю следующую ошибку:
XMLHttpRequest не удается загрузить http://api.example.com/Account/Login. Ответ на предварительный запрос не проходит проверку контроля доступа: нет Заголовок "Access-Control-Allow-Origin" присутствует на запрошенном ресурс. Происхождение'http://app.example.com ' поэтому не допускается доступ.
мой PHP код выглядит так:
$http_origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = array(
'http://example.com',
'https://example.com',
'http://app.example.com',
'https://app.example.com',
'http://www.example.com',
'https://www.example.com'
);
if (in_array(strtolower($http_origin), $allowed_domains))
{
// header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Origin: $http_origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin");
exit(0);
}
мой угловой пост выглядит так:
public login(login: Login): Observable<LoginResponse> {
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password));
return this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers })
.map(response => {
// code
});
}
если я запускаю запрос через почтальона, который не беспокоиться Корс, я получаю:
{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }
Я попытался установить origin на'*
' просто проверить и посмотреть, если это было ядро проблемы, и он по-прежнему терпит неудачу таким же образом.
редактировать Просто обновление информации ниже. Изменение кожуха в заголовках не имело никакого эффекта, и вытаскивание кода из их операторов if не имело никакого эффекта.
Я отладил php, сказав моему живому приложению перейти к моему локальному api, и php работает так, как ожидалось. Это установка заголовков и внесение их в каждый из операторов if.
редактировать дубль 2 Мне действительно нужна помощь в этом, если у кого-то есть идеи, я был бы очень признателен.
изменить, взять 3 Если я установлю все заголовки в свой .htaccess, а не мой php, он позволяет мне пройти. Однако теперь я застрял на ошибке, указанной выше, которую я всегда получаю при использовании postman, однако теперь это при использовании фактический сайт.
{"error":"invalid_client","error_description":"Client credentials were not found in the headers or body"}
мои заголовки ответов похожи на so
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:authorization, content-type, accept, origin
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*
Я буду менять его с * только на мои домены, как только он будет работать. Но пока я оставлю все как есть.
мои заголовки по запросу.
2 ответов
OK у меня недавно были подобные проблемы, и я решил все только на стороне бэкэнда с no .реврайт вещи.
когда браузер отправляет кросс-серверные запросы, он сначала отправляет запрос опций, чтобы убедиться, что он действителен, и он может отправить "реальный" запрос. После того, как он получает правильный и действительный ответ от OPTIONS, только тогда он отправляет "реальный" запрос.
теперь для обоих запросов на бэкэнде вам нужно обязательно вернуть правильные заголовки: content-type, allow-origin, allow-headers и т. д...
убедитесь, что в запросе опций на бэкэнде приложение возвращает заголовки и возвращает ответ, не продолжая полный поток приложения.
в" реальном " запросе вы должны вернуть правильные заголовки и тело регулярного ответа.
пример:
//The Response object
$res = $app->response;
$res->headers->set('Content-Type', 'application/json');
$res->headers->set('Access-Control-Allow-Origin', 'http://example.com');
$res->headers->set('Access-Control-Allow-Credentials', 'true');
$res->headers->set('Access-Control-Max-Age', '60');
$res->headers->set('Access-Control-Allow-Headers', 'AccountKey,x-requested-with, Content-Type, origin, authorization, accept, client-security-token, host, date, cookie, cookie2');
$res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
if ( ! $req->isOptions()) {
// this continues the normal flow of the app, and will return the proper body
$this->next->call();
} else {
//stops the app, and sends the response
return $res;
}
запомните:
Если вы используете: "Access-Control-Allow-Credentials" = true убедитесь, что "Access-Control-Allow-Origin "не является"*", он должен быть установлен с соответствующим доменом! (здесь пролилось много крови:/)
определите разрешенные заголовки, которые вы получите в " Access-Control-Allow-Headers" если вы не определите их, запрос не будет выполнен
Я добавил ниже в PHP, и это решило мою проблему.
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type, origin");