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, что может быть полезно.