8

I am calling a http post in Angular 2. This is working fine in post man but when I implement this API call in Angular 2 I get No 'Access-Control-Allow' error. Here is my code

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            headers.append('Access-Control-Allow-Origin','*');
            let options = new RequestOptions({ headers: headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,options)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

Or can I do this? Just pass header instead of options

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            //headers.append('Access-Control-Allow-Origin','*');
          //  let options = new RequestOptions({ headers:headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,headers)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }
1
  • You can pass headers directly (I guess it needs to be an object like {headers} (not sure though) but that's not related to your CORS error at all. Commented Aug 17, 2016 at 17:02

2 Answers 2

11

CORS headers like

headers.append('Access-Control-Allow-Origin','*');

need to be provided by the server. Adding them on the client is pointless.

Sign up to request clarification or add additional context in comments.

2 Comments

i am using an 3rd party api so how can i add headers over there
This probably means the owner doesn''t want xou to use the API this way. You can workaround by relaying the requests through a server you control. CORS us only relevant for requests made from a browser, not from a server.
3

When using non-standard headers (json is apparently considered non-standard) then a pre-flight check is carried out to ask if the requested action (in this case 'post') can be carried out. Only the server can respond with the permissive headers. How you respond does depend on your server language. In my webapi2 I implement cors in the WebAppConfig

 var cors = new EnableCorsAttribute("http://localhost:3000", "*", "GET, HEAD, OPTIONS, POST, PUT");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

Note for a live server you would replace the localhost ref with a web configed list ( or specific location where the caller resides). The SupportsCredentials is only needed if you are using authentication.

To handle the pre-flight I added a method to Globals.asax which just intercepts pre-flight messages and returns enough data for the post to move ahead.

protected void Application_BeginRequest()
    {
        if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
        {
            var origin = HttpContext.Current.Request.Headers["Origin"];

            Response.Headers.Add("Access-Control-Allow-Origin", origin);
            Response.Headers.Add("Access-Control-Allow-Headers", "content-type, withcredentials, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT");

            Response.Flush();
        }
    }

Note here that I am cheating somewhat by reflecting the origin back - this is not safe in a production environment and should list the specific servers otherwise you are being too loose with security.

Be aware that there are some dev cheats. - If you run on internet explorer on localhost (for dev purposes) then ie ignores the port which most other browsers do not so making things easier. There is also a CORS enhancement for Chrome which adds the headers for you. Finally you will see a lot of code that uses '*' returns (to permit all) - by all means use them to get the code working but before release lock these down far more aggressively.

2 Comments

I don't really understand you when you say Only the server can respond with the permissive headers. And later There is also a CORS enhancement for Chrome which adds the headers for you. Chrome is on the client side no?
would recommend you investigate what the Chrome CORS enhancement does which should clear up your confusion. That enhancement can solve a limited problem in a DEV environment. The full answer is needed for production.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.