12

I'm working on a project using Ionic 2 (2.0.0-beta.10). I try to pass an authorization token with the request. However the header is not being sent. Also other headers I tried to pass with the request are not being sent.

let url = 'http://www.example.com/savedata';
let data = JSON.stringify({ email: 'test@test.com', 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!");
});

My REST API receives this request with the following headers:

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  

The data (body) comes in correct, only the headers problem I cannot resolve. Any help would be very appreciated.

Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
GwenTiana
  • 121
  • 1
  • 4
  • 1
    Can you try to pass headers like this `this.http.post(url, data, {headers:headers})....` – null canvas Aug 04 '16 at 19:48
  • I tried to do this, but the headers I receive in the REST API upon sending the request are the following: Host www.example.com Connection keep-alive Content-Length 45 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 Content-Type text/plain Accept */* Referer http://localhost:8100/?restart=794567 Accept-Encoding gzip, deflate Accept-Language en-US,en;q=0.8 – GwenTiana Aug 04 '16 at 20:27
  • 1
    ok, check this answer http://stackoverflow.com/questions/38301878/ionic-2-angular-2-http-headers-are-not-being-sent-along-with-the-request – null canvas Aug 05 '16 at 04:57
  • 1
    Thanks, I did already read this issue. However none of the answers actually describes the solution of this issue. According to Bala Abhinav, he managed to solve the problem, but he didn't mention how.... "The problem was a CORS issue. It is solved now. thanks. – Bala Abhinav" – GwenTiana Aug 05 '16 at 16:01
  • 1
    Are you setting what headers are authorized in your REST API? `Access-Control-Allow-Headers: Authorization` – Aguardientico Sep 08 '16 at 03:00
  • Duplicate: http://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a-get-request – Quentin Sep 13 '16 at 14:25
  • @GwenTiana — The solution is that the server has to respond with permission. The specifics of that depend on what server and/or server side language you are using. – Quentin Sep 13 '16 at 14:26
  • did you solve this ? @GwenTiana . This not a CORS issue. I have two apps, one with ionic 1 and other with ionic 2. Same http call (same endpoint) works on ionic v1 app , but headers are not sent in ionic 2 app. Same http call works on Angular 2 web app too. – UzUmAkI_NaRuTo Dec 08 '16 at 08:12
  • Did you ever get this solved? – SemajDraw Nov 23 '18 at 21:04

5 Answers5

1

This question has an answer here: https://stackoverflow.com/a/45286959/4119650

Headers.append() does not update the object, it returns a clone of it. By instantiating the Headers object and then calling headers.append(), the result of that append isn't being used. Instead, you may need to do this:

headers: Headers = new Headers().append('Content-Type', 'application/json').append('Authorization', 'Bearer ' + "tokenContent");

Headers is deprecated anyway, and should be replaced with HttpHeaders and HttpClient. https://angular.io/api/common/http/HttpHeaders https://angular.io/guide/http

0

Try to use HttpClient. It is easiest and latest one.

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: 'test@test.com', 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().
}
Silambarasan R
  • 1,346
  • 15
  • 22
-1

If you are calling REST API (example.com in your example) that is located on a different domain from your Angular 2 / Ionic app ( evil.com in your example), then you need to configure REST API server to return this header:

Access-Control-Allow-Origin: http://evil.com 

Which will allow the browser to send async HTTP requests from evil.com host to the rest api server.

It is done by enabling CORS on the rest api server, you can read about it a bit more.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Several libraries for the backend that enable cross origin requests:

https://github.com/expressjs/cors - NodeJS/Express

https://pypi.python.org/pypi/Flask-Cors/ - Python cors library for Flask

and the list continues for almost any other backend framework.

Stanley Kirdey
  • 602
  • 5
  • 20
-1

Stringify JSON this not realy working at all times. First you need to convert your JSON data to StringQuery to be understand by the server properly and much faster way.

public StringQuery(jsonString) {
        return Object.keys(jsonString).map(function (key) {
          return encodeURIComponent(key) + '=' + encodeURIComponent(jsonString[key]);
        }).join('&');
      }   

then you make your post function or method

public post(){
let url = 'http://www.example.com/savedata';
let data = this.StringQuery({ email: 'test@test.com', 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!");
    });
}

I use this code too and get success post request.

Jakegarbo
  • 1,201
  • 10
  • 20
-1

For sending and receiving you might be using one server ex:Nginx Config file in sites-enabled for backend ,there you have to add Access-Control-Allow-Origin: * or http://localhost that can be helpful.