Angular2 Заголовки
Когда я вызываю сервер без заголовков, его работа и сервер возвращают json:
this.http.get(url)
но когда я добавляю заголовок:
var headers = new Headers({'x-id': '1'});
this.http.get(url, {'headers': headers})
браузер возвращает ошибку:
XMLHttpRequest cannot load http://domain/api/v1/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Я также попытался добавить Origin
заголовок - ошибка браузера: Refused to set unsafe header "Origin"
И Access-Control-Allow-Origin
header - без эффекта
На сервере (Laravel) я создал промежуточное ПО Cors.php
:
<?php
namespace App\Http\Middleware;
use Closure;
class Cors {
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', 'http://localhost:3000')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'x-id');
}
}
Я новичок в angular2 и запросах CORS, не знаю, что делать.
- Angular: 2.0.0-beta.0
- Laravel: 5.0
- Браузер: Google Chrome
Ответы
Ответ 1
Предварительно запрошенный запрос с CORS означает, что HTTP-запрос OPTIONS выполняется до фактического. Вы переключаетесь с простого запроса на тот, поскольку вы добавляете настраиваемый заголовок в случае метода GET. Эта ссылка может помочь вам понять, что происходит: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/.
FYI заголовок Origin
автоматически добавляется браузером при выполнении запроса кросс-домена.
Я думаю, что ваша проблема находится в заголовке Access-Control-Allow-Origin
. Вы должны установить хост, который выполняет вызов, а не адрес сервера. Вы должны иметь это вместо этого (если ваше приложение Angular2 работает на localhost:8080
):
return $next($request)
->header('Access-Control-Allow-Origin', 'http://localhost:8080')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'x-id');
Надеюсь, это поможет вам,
Thierry
Ответ 2
У меня была такая же проблема в моем приложении Angular2.
Проблема, как уже было сказано, заключается в том, что перед каждым запросом, сделанным клиентом, на сервер отправляется запрос предварительной проверки.
Этот тип запроса имеет тип OPTIONS, и он обязан отправить сервер обратно ответный сигнал перед полетом со статусом 200 и заголовками, установленными для приема запросов от этого клиента.
Это мое решение (с выражением):
// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');
// Set to true if you need the website to include cookies in requests
res.setHeader('Access-Control-Allow-Credentials', true);
// Check if Preflight Request
if (req.method === 'OPTIONS') {
res.status(200);
res.end();
}
else {
// Pass to next layer of middleware
next();
}
Таким образом, клиент будет авторизован, и вы сможете настроить свои собственные заголовки во всех запросах. В вашем случае вам нужно установить x-id в опции Access-Control-Allow-Headers.
Ответ 3
В вашем случае сервер должен ответить на запрос перед полетом следующими заголовками:
Access-Control-Allow-Origin: *
X-Custom-HeaderAccess-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-id
Обратите внимание, что для заголовка HTTP Access-Control-Allow-Origin лучше всего установить домен, в котором приложение angular2 размещено явно, а не *, которое необходимо только для общедоступного API где вы не контролируете всех потребителей!
Я настоятельно рекомендую вам прочитать следующую статью о CORS:
http://www.html5rocks.com/en/tutorials/cors/
Ответ 4
Я разрабатывал приложение angular2
с концом c# web api
и столкнулся с проблемой с настройками cors
.
Реальная проблема оказалась не в настройках cors
, а в том, что данные, отправляемые в api (js date object to С# datetime type, не выстроились правильно). Однако, в вашем случае, абсолютно необходимо передать x-id в заголовке, а не как параметр в запросе? Например, вы могли бы сделать что-то вроде этого:
getYourDataType(id: number): Observable<YourDataType> {
return this.http.get(url + '/' + id.toString())
.map((response: Response) => <YourDataType>response.json());
Из моих исследований после решения этой проблемы кажется, что angular
попытается найти конечную точку, которую вы пытались ударить, не смог ее найти, а затем предположил, что причина должна быть чем-то неправильным с настройками cors, а не данные клиентской стороны.
Вы сказали, что api возвращает данные, когда вы не устанавливаете заголовки в своем запросе, поэтому, если переключение с заголовка на параметр не работает, вы можете попробовать проверить запрос с помощью инструмента, такого как скрипач или сеть вкладку инструментов chrome dev и посмотрите, построил ли angular каждый запрос, как вы ожидаете, он должен иметь. Или, сравнивая результаты, вручную создавая запрос в скрипаче, может быть очень хорошо освещено то, что именно происходит, чтобы дать вам этот неожиданный ответ.
В любом случае, выяснив, что проблема с вашими данными, а не с настройками cors
, довольно сложно. angular
Вы смотрите на совершенно неправильную вещь, пытающуюся выяснить очень простую проблему. Надеюсь, это поможет кому-то.
Ответ 5
проблема в том, что вам также необходимо установить разрешенные заголовки. Вот почему он не работает. Чтобы заставить его работать с простым angular2 http-запросом, вам нужно добавить следующие заголовки:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept"); // In your case also add x-id or what you are also using.
header('Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS');
Ответ 6
Попробуйте использовать следующий код. Это должно работать
let headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('x-id','1');
this.http.get(url, {'headers': headers}).subscribe(
response => {...},
error => {...}
);