Ionic 2/Angular 2/CORS: заголовки HTTP не отправляются с запросом
Я работаю над проектом с использованием Ionic 2 (2.0.0-beta.10). Я пытаюсь передать токен авторизации с запросом. Однако заголовок не отправляется. Также не отправляются другие заголовки, которые я пытался передать с запросом.
let url = 'http://www.example.com/savedata';
let data = JSON.stringify({ email: '[email protected]', password: '123456' });
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer ' + "tokenContent");
let options = new RequestOptions({ headers: headers });
this.http.post(url, data, options).map(res => res.json()).subscribe(data => {
console.log("it worked");
}, error => {
console.log("Oooops!");
});
Мой REST API получает этот запрос со следующими заголовками:
Host: www.example.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://evil.com/
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Access-Control-Request-Headers: authorization, content-type
Accept: */*
Referer: http://localhost:8100/?restart=794567
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Данные (тело) поступают правильно, только проблема с заголовками, которые я не могу решить.
Любая помощь будет очень оценена.
Ответы
Ответ 1
На этот вопрос есть ответ здесь:
fooobar.com/questions/196173/...
Headers.append()
не обновляет объект, а возвращает его клон. Создавая объект Headers и затем вызывая headers.append()
, результат этого append
не используется.
Вместо этого вам может потребоваться сделать следующее:
headers: Headers = new Headers().append('Content-Type', 'application/json').append('Authorization', 'Bearer ' + "tokenContent");
Headers
в любом случае устарела и должна быть заменена на HttpHeaders
и HttpClient
.https://angular.io/api/common/http/HttpHeaders
https://angular.io/guide/http
Ответ 2
Попробуйте использовать HttpClient. Это самый простой и последний.
constructor(private http: HttpClient) {}
...
...
postData() {
const httpHeaders = new HttpHeaders({
'Content-Type' : 'application/json',
'Cache-Control': 'no-cache',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers': 'Origin, Accept, Access-Control-Allow-Origin, Content-Type, Authorization, X-Requested-With'
});
let url = 'http://www.example.com/savedata';
let data = JSON.stringify({ email: '[email protected]', password: '123456' });
this.http.post(url, data, { headers: httpHeaders, observe: 'response'}).subscribe(data => {
console.log("it worked");
}, error => {
console.log("Oooops!");
}); // Here you don't need to use map().
}
Ответ 3
Если вы вызываете REST API (example.com в своем примере), который находится в другом домене из вашего приложения Angular 2/Ionic (evil.com в вашем примере), вам необходимо настроить сервер REST API для возврата этого заголовка:
Access-Control-Allow-Origin: http://evil.com
Это позволит браузеру отправлять асинхронные HTTP-запросы от узла evil.com к остальному серверу api.
Это делается путем включения CORS на остальном сервере api, вы можете прочитать об этом немного больше.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Несколько библиотек для бэкэнд, которые разрешают запросы на перекрестный поиск:
https://github.com/expressjs/cors - NodeJS/Express
https://pypi.python.org/pypi/Flask-Cors/ - Библиотека Python cors для Flask
и список продолжается почти для любых других бэкэнд-фреймов.
Ответ 4
Stringify JSON это не работает постоянно.
Сначала вам нужно преобразовать данные JSON в StringQuery, чтобы понимать сервер правильно и намного быстрее.
public StringQuery(jsonString) {
return Object.keys(jsonString).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(jsonString[key]);
}).join('&');
}
тогда вы выполняете свою функцию или метод post
public post(){
let url = 'http://www.example.com/savedata';
let data = this.StringQuery({ email: '[email protected]', password: '123456' })
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization', 'Bearer ' + "tokenContent");
let options = new RequestOptions({ headers: headers });
this.http.post(url, data, options).map(res => res.json()).subscribe(data => {
console.log("it worked");
}, error => {
console.log("Oooops!");
});
}
Я тоже использую этот код и получаю успешный почтовый запрос.
Ответ 5
Для отправки и получения вы можете использовать один сервер, например: Nginx
Файл конфигурации на сайтах с поддержкой для бэкэнда, там вы должны добавить Access-Control-Allow-Origin: * или http://localhost, что может быть полезно.