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

AngularWebpackHeaderCors

Angular Problem Overview


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]

Angular Solutions


Solution 1 - Angular

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.

Solution 2 - Angular

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 "*"

Solution 3 - Angular

I have spent lot of time for solution and got it worked finally by making changes in the server side.Check the website https://docs.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(); }

Solution 4 - Angular

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][1] [1]: http://i.stack.imgur.com/T417c.png

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

Solution 5 - Angular

Simply you can set in php file as

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

Solution 6 - Angular

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.

Solution 7 - Angular

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.

Solution 8 - Angular

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

Solution 9 - Angular

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.

Solution 10 - Angular

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

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

Solution 11 - Angular

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.

Solution 12 - Angular

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

Solution 13 - Angular

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionphilip yooView Question on Stackoverflow
Solution 1 - AngularPablo Ezequiel InchaustiView Answer on Stackoverflow
Solution 2 - AngularNitheesh K PView Answer on Stackoverflow
Solution 3 - AngularsatishView Answer on Stackoverflow
Solution 4 - AngularAbnerView Answer on Stackoverflow
Solution 5 - AngularPrakash PazhanisamyView Answer on Stackoverflow
Solution 6 - AngularJunView Answer on Stackoverflow
Solution 7 - AngulardrewwyattView Answer on Stackoverflow
Solution 8 - AngularSibirajView Answer on Stackoverflow
Solution 9 - AngularLuca BasilicoView Answer on Stackoverflow
Solution 10 - AngularMoh-OthmanovicView Answer on Stackoverflow
Solution 11 - AngularSudheer KumarView Answer on Stackoverflow
Solution 12 - AngularJ. JerezView Answer on Stackoverflow
Solution 13 - AngularRameez RamiView Answer on Stackoverflow