Search code examples
angularbrowser-syncmixed-contentangular2-httplite-server

Angular2 http.get results in a Mixed Content error or No 'Access-Control-Allow-Origin' header


I am trying but unable to do a http.get request.

Below is the relevant parts of the Service I am using.

import { Injectable } from '@angular/core';
import { Http, Response, Headers,RequestOptions } from '@angular/http';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class StockService {

constructor(private http: Http) { }

    getStocks() {
        var url = "http://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np";
        this.http.get(url).toPromise().then(function(info){
            console.log(info);
        });
    }
}

I know that the url http://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np is valid because I am able to run a get request with it in Postman.

I am using npm-lite to run my app and it gets loaded at http://localhost:3000

Running at http://localhost:3000 results in the error : XMLHttpRequest cannot load http://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

I thought that the problem could be that my app is running on http and needed to be on a https to properly do the get request, so I created a bs.config.json file. npm-lite allows us to use options from browser-sync to run. I set the https to be true to allow my app to run on https.

bs-config.json

{
    "https" : true
}

Now when I run my app it will run on 'https://localhost:3000' and I get the error: zone.js:101Mixed Content: The page at 'https://localhost:3000/portfolio' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np'. This request has been blocked; the content must be served over HTTPS.

I am unsure of how to proceed from here. Please let me know if I am properly setting up a http get request or if I am misunderstanding something. Thanks!

============================================

EDIT 1: in response to @AngJobs recommendation of : just add a special header in your request for cross browser request

I added a header in the request :

getStocks() {
    var url = "http://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np";
    let headers = new Headers({ 'Access-Control-Allow-Origin': '*'});
    let options = new RequestOptions({ headers: headers });
    this.http.get(url, options).toPromise().then(function(info){
        console.log(info);
    });
}

I am back to running on http://localhost:3000 but now get the error: XMLHttpRequest cannot load https://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np. Response for preflight is invalid (redirect)


Solution

  • So the ultimate problem was that the yahoo servers were not authenticating CORs. A simple solution to solve this is to use a proxy. The one I am using for now is : https://crossorigin.me/. In order to use this proxy, I just need to append the request url with https://crossorigin.me/.

    There is no need to mess with request headers and I can continue to run the app on http:localhost

    getStocks() {
        var url = "https://crossorigin.me/https://finance.yahoo.com/d/quotes.csv?s=AAPL&f=np";
        this.http.get(url).toPromise().then(function(response){
            console.log(response._body);
        });     
    }