3

I'm working on an Ionic 2 Application, which use third-party API from Oxford Dictionary. Their API require app_id and app_key as authentication step to work.

Here is the service which make the GETrequest call to the API

@Injectable()
export class OxfordVocabularyService {
  private app_id: any;
  private app_key: any;
  private OxfordBaseRequestURL: any;
  constructor(private http: Http) {
    this.app_id = configuration.oxfordAPI.app_id;
    this.app_key = configuration.oxfordAPI.app_key;
    this.OxfordBaseRequestURL = configuration.oxfordAPI.requestURL;
  }


  public getWordIPA(word: String): Promise<any> {
    let headers = new Headers({ 'Accept': 'application/json' });
    headers.append('app_id', this.app_id);
    headers.append('app_key', this.app_key);
    let options = new RequestOptions({ headers: headers });
    return this.http.get(this.OxfordBaseRequestURL + word + '/pronunciations', options).toPromise().then(response => {
      console.log(response.json());
    });
  }

When the app run the service call, it throws err enter image description here

More request info on browser: enter image description here enter image description here

The API request works perfectly fine on Postman enter image description here

I have attached the app_id and app_key on headers request, so why do i get the error.

403 - Authentication Parameters missing

Is this something related to CORS ? Can you show me the way to make the API call properly ?

Update

Huge thanks to @suraj and @n00dl3, i have solved the problem by adding a proxy to the Ionic Configuration.

ionic.config.json

 "proxies": [
    {
      "path": "/oxfordapi",
      "proxyUrl": "https://od-api.oxforddictionaries.com/api/v1/entries/en"
    }
  ]

And change the GET request path to

this.http.get('oxfordapi/' + word + '/pronunciations', options)
ThangLeQuoc
  • 2,272
  • 2
  • 19
  • 30
  • are you trying with `ionic serve`? – Suraj Rao Apr 24 '17 at 09:48
  • @suraj yes, i'm using `ionic serve` command. Is that a problem ? – ThangLeQuoc Apr 24 '17 at 09:51
  • 2
    it id likely a cors issue only.. this only happens in browser.. set a proxy for ionic serve like [this answer](http://stackoverflow.com/questions/37763775/no-access-control-allow-origin-header-is-present-upon-ionic2-http-post-request/37779476#37779476) – Suraj Rao Apr 24 '17 at 09:53

4 Answers4

4

It seems Oxford dictionnaries API does not support CORS :

Sometimes pre-flight requests will produce the error message “No 'Access-Control-Allow-Origin' header is present on the requested resource.”

Unfortunately, we are unable to support client-side application requests (this includes JavaScript, JScript, VBScript, Java applets, ActionScript, etc.).

This is because our API does not currently support CORS requests due to the potential implications for the security of our server. Instead, we suggest you to make the query reach your server side application, and then send the API request from the server rather than from the client.

source

So you need to create a proxy for ionic serve (that will not happen on the packaged iOS/Android app as there is no preflighted requests).

for creating a ionic proxy, see this answer

Community
  • 1
  • 1
n00dl3
  • 21,213
  • 7
  • 66
  • 76
0

add this into options "withCredentials: true".

option should be like let options = new RequestOptions({ withCredentials: true,headers: headers});

Shailesh Ladumor
  • 7,052
  • 5
  • 42
  • 55
  • 1
    New error on console: "Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:8100' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute." – ThangLeQuoc Apr 24 '17 at 10:00
0

While using chrome browser you can you chrome extension.CORS

Ketan Akbari
  • 10,837
  • 5
  • 31
  • 51
0

In case anyone is trying to connect to the Oxford API using Angular alone, without Ionic, the above solution by @n00dl3 works pretty much the same, but with an important change.

You have to configure your angular-cli proxy (proxy.conf.json) as follows:

{
  "/oxfordapi": {
    "target": "https://od-api.oxforddictionaries.com/api/v1/entries/en/",
    "secure": true,
    "changeOrigin": true,
    "logLevel": "debug",
    "headers": {
      "Accept": "application/json",
      "app_id": "YOUR APP ID",
      "app_key": "YOUR APP KEY"
    },
    "pathRewrite": {"^/oxfordapi" : ""}
  }
}

Then do an HTTP get request from somewhere in your Angular component like this:

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';

@Component({
  selector: 'posts',
  templateUrl: './posts.component.html',
  styleUrls: ['./posts.component.css']
})
export class PostsComponent implements OnInit {

    word: string = "aardvark"

    ngOnInit() {
      this.getWord(this.word)
    }

    getWord(word) {
      this.http.get('/oxfordapi/' + word)
        .subscribe(response => {
          console.log(response.json())
        })
    }
}

You should now see the dictionary entry for "aardvark" in your console. Then launch your app using:

ng serve --proxy-config proxy.conf.json
JP Lew
  • 4,121
  • 2
  • 32
  • 45