3

I am trying to use Twitter API in my app.

When I run it from Postman, it works great.

Postman

However, when I run it from my app, using Google Chrome I get

XMLHttpRequest cannot load https://api.twitter.com/1.1/search/tweets.json?q=canada. 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. The response had HTTP status code 400.

Here is my code for it

...

     getTweets(hashtag : string){
        var headers = new Headers();
        headers.append('Authorization', 'Bearer AAAAAAAAAAAAAAAAAAAAAONruQAAAAAAfxQda4njz64axXN9sw4U0oU%3Dr1niTwKwXoOZXmZczDKgN0wWHWEMPrPcnXXMgVQhiTIzays7J');
        var requestOptions = new MyRequest();
        requestOptions.headers = headers;

      return this.http.get('https://api.twitter.com/1.1/search/tweets.json?q=montreal', requestOptions);  
    }
}

class MyRequest implements RequestOptionsArgs {
    public headers: Headers;
}
CodyBugstein
  • 21,984
  • 61
  • 207
  • 363
  • You have not added the `Access-Control-Allow-Origin` header to your headers. The error is clearly telling you that it's required. – Brad Apr 09 '16 at 02:02

1 Answers1

0

The Twitter API doesn't support CORS but JSONP. So you need the leverage the JSONP support of Angular2.

Here is à sample. First specify the corresponding providers when bootstrapping your application:

import {bootstrap} from 'angular2/platform/browser'
import {JSONP_PROVIDERS} from 'angular2/http'
import {AppComponent} from './app.component'

bootstrap(AppComponent, [ JSONP_PROVIDERS ]);

Then inject the Jsonp class (instead of the Http one) and use it to make your request:

export class AppComponent {
  constructor(jsonp:Jsonp) {
    var url = 'https://api.twitter.com/1.1/search/tweets.json?q=montreal&callback=JSONP_CALLBACK';

    var headers = new Headers();
    headers.append('Authorization', 'Bearer AAAAAAAA(...)sw4U0oU%');

    jsonp.request(url, { method: 'Get', headers: headers })
     .subscribe((res) => {
       this.result = res.json()
     });

See rhis question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Thanks but unfortunately this isn't working. I get a 400 or 401 error, and when I look in devtools I don't even see Authorization as one of the headers, so I fear the syntax for adding the headers is not correct – CodyBugstein Apr 10 '16 at 06:03
  • I just read this in the doc regarding the callback parameter: "If supplied, the response will use the JSONP format with a callback of the given name. The usefulness of this parameter is somewhat diminished by the requirement of authentication for requests to this endpoint.". See https://dev.twitter.com/rest/reference/get/search/tweets. – Thierry Templier Apr 10 '16 at 14:53
  • Do you import the `Headers` class? `import {Http, Headers, ...} from 'angular2/http'`. Without it in the imports, the headers aren't sent and there is no error message... – Thierry Templier Apr 10 '16 at 14:54
  • Yes, you're right! We can send headers since jsonp relies on the adding of a script tag in the HTML page... – Thierry Templier Apr 10 '16 at 15:03
  • We can or *can't*? – CodyBugstein Apr 10 '16 at 15:32
  • what good is accessing Twitter API via jsonp when you first have to authenticate your app? Authentication through Twitter requires a POST and your cannot POST via jsonp. How do you interact with Twitter API when Twitter API does not support CORS by setting 'Access-Control-Allow-Origin' in pre-flight OPTIONS? – Tom Schreck Nov 15 '16 at 20:13