philip yoo
philip yoo

Reputation: 2522

No 'Access-Control-Allow-Origin' header in Angular 2 app

For this project, I'm just learning and practicing Angular 2. I have no server-side and am making API requests to barchart ondemand api .

I'm wondering if it is possible to bypass the cors issue. I'm still fairly new to all this, so baby-step instructions are really appreciated! I'm using http://localhost:8080.

Error message: (api key commented out)

XMLHttpRequest cannot load http://marketdata.websol.barchart.com/getHistory.json?key=MY_API_KEY&symbol=GOOG&type=daily&startDate=20150311000000. 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:8080' is therefore not allowed access.

StockInformationService:

import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import {Observable} from 'rxjs/Rx';

@Injectable()
export class StockInformationService {
    private apiRoot = "http://marketdata.websol.barchart.com/getHistory.json?key=MY_API_KEY&";

    constructor (private _http: Http) {}

    getData(symbol: string): Observable<any> {
        // Tried adding headers with no luck
        const headers = new Headers();
        headers.append('Access-Control-Allow-Headers', 'Content-Type');
        headers.append('Access-Control-Allow-Methods', 'GET');
        headers.append('Access-Control-Allow-Origin', '*');

        return this._http.get(this.apiRoot + "symbol=" + symbol + "&type=daily&startDate=20150311000000", {headers: headers})
            .map(response => response.json());
    }
}

App Component:

import {Component} from "angular2/core";
import {VolumeComponent} from '../../components/volume/volume';
import {StockInformationService} from '../../core/stock-information.service';

@Component({
    selector: 'app-shell',
    template: require('./app-shell.html'),
    directives: [VolumeComponent],
    providers: [StockInformationService]
})
export class AppShell {
    constructor(private _stockInformationService: StockInformationService) {}

    // In my template, on button click, make api request
    requestData(symbol: string) {
        this._stockInformationService.getData(symbol)
            .subscribe(
                data => {
                    console.log(data)
                },
                error => console.log("Error: " + error)
            )}
    }

}

In my console, the requestData Error: Error: [object Object]

Upvotes: 61

Views: 341444

Answers (13)

J. Jerez
J. Jerez

Reputation: 794

this is server configuration, set up config.addAllowedHeader("*"); in the CorsConfiguration.

Upvotes: 1

Rameez Rami
Rameez Rami

Reputation: 5728

Most of the time this happens due to the invalid response type from server.

Make sure the following 2 to avoid this issue..

  1. You don't need to set any CORS headers in Angular side. it very well know how to deal with it. Angular expects the return data to be in json format. so make sure the return type is JSON even for the OPTIONS request.
  2. You Handle CORS in server side by using CORS header which is very self explanatory or you can google how to set CORS headers or middlewares.

Upvotes: 0

Sudheer Kumar
Sudheer Kumar

Reputation: 471

I had the same problem when I was practising Angular5. Then I came across https://spring.io/guides/gs/rest-service-cors/ which helped me to resolve the issue.

I have kept @CrossOrigin(exposedHeaders="Access-Control-Allow-Origin") on my request mapping method. We can also configure this globally in spring boot application.

Upvotes: 1

satish
satish

Reputation: 155

I have spent lot of time for solution and got it worked finally by making changes in the server side.Check the website https://learn.microsoft.com/en-us/aspnet/core/security/cors

It worked for me when I enabled corse in the server side.We were using Asp.Net core in API and the below code worked

1) Added Addcors in ConfigureServices of Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
        services.AddMvc();
    }

2) Added UseCors in Configure method as below:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseCors(builder =>builder.AllowAnyOrigin());
        app.UseMvc();
    }

Upvotes: 9

Moh-Othmanovic
Moh-Othmanovic

Reputation: 11

I got the same error and here how I solved it, by adding the following to your spring controller:

@CrossOrigin(origins = {"http://localhost:3000"})

Upvotes: 1

Prakash Pazhanisamy
Prakash Pazhanisamy

Reputation: 983

Simply you can set in php file as

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

Upvotes: 9

Luca Basilico
Luca Basilico

Reputation: 191

If you are creating a mock-up with SoapUI,a free testing tool for REST and SOAP request and response, for Angular 2+ application you should remember to set inside your http header request

 Access-Control-Allow-Origin :  *

I add two images for helping your insert. The first shows the header you should add. If you want to add the header before you have to click the plus button(it's green).

First image

The second image shows the insert the *. The value * permits to accept all the request from different hosts.

Second image

After this work my Angular application removed this annoying error in my console.

error inside console

A big recourse that helped me to understand for creating my first mock up is this video. It will help you for creating a new mock-up inside SoapUi's environment without a server-side.

Upvotes: 1

Sibiraj
Sibiraj

Reputation: 4756

Another simple way, without installing anything

  1. HTTP function

    authenticate(credentials) {
    
    let body = new URLSearchParams();
    body.set('username', credentials.username);
    body.set('password', credentials.password);
    
    return this.http.post(/rest/myEndpoint, body)
      .subscribe(
      data => this.loginResult = data,
      error => {
        console.log(error);
      },
      () => {
      // function to execute after successfull api call
      }
      );
     }
    
  2. Create a proxy.conf.json file

    {
     "/rest": {
    "target": "http://endpoint.com:8080/package/",
    "pathRewrite": {
      "^/rest": ""
    },
    "secure": false
    }
    }
    
  3. then ng serve --proxy-config proxy.conf.json (or) open package.json and replace

    "scripts": {
    "start": "ng serve --proxy-config proxy.conf.json",
     },
    

and then npm start

That's it.

Check here https://webpack.github.io/docs/webpack-dev-server.html for more options

Upvotes: 2

Pablo Ezequiel Inchausti
Pablo Ezequiel Inchausti

Reputation: 20713

This a problem with the CORS configuration on the server. It is not clear what server are you using, but if you are using Node+express you can solve it with the following code

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

that code was an answer of @jvandemo to a very similar question.

Upvotes: 47

Abner
Abner

Reputation: 622

I also had the same issue while using http://www.mocky.io/ what i did is to add in mock.io response header: Access-Control-Allow-Origin *

To add it there just need to click on advanced options

Mock.io Header Example Once this is done, my application was able to retrieve the data from external domain.

Upvotes: 7

Jun
Jun

Reputation: 86

I also encountered the same problem and passed the following way to solve this problem.

step 1:

$ npm install --save-dev http-proxy-middleware

step 2:

add a proxy when i fetch web api, if you use lite-server you can add a file bs-config.js .

//file: bs-config.js
var proxyMiddleware = require('http-proxy-middleware');

module.exports = {
    server: {
        middleware: {
            1: proxyMiddleware('/example-api', {
                target: 'http://api.example.com',
                changeOrigin: true,
                pathRewrite: {
                '^/news-at-api': '/api'
                }
            })
        }
    }
};

hope this helps.

Upvotes: 6

Nitheesh K P
Nitheesh K P

Reputation: 1110

You can read more about that from here: http://www.html5rocks.com/en/tutorials/cors/.

Your resource methods won't get hit, so their headers will never get set. The reason is that there is what's called a preflight request before the actual request, which is an OPTIONS request. So the error comes from the fact that the preflight request doesn't produce the necessary headers. check that you will need to add following in your .htaccess file:

Header set Access-Control-Allow-Origin "*"

Upvotes: 17

drewwyatt
drewwyatt

Reputation: 6027

Unfortunately, that's not an Angular2 error, that's an error your browser is running into (i.e. outside of your app).

That CORS header will have to be added to that endpoint on the server before you can make ANY requests.

Upvotes: 3

Related Questions