71

I've a problem when I try to do PATCH request in an angular 7 web application. In my backend I have:

app.use((req, res, next) => {
    res.set({
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "Access-Control-Allow-Headers": "'Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token'",
    });

    next();
});

In my frontend service, I've:

  patchEntity(ent: any, id) {
    let headers = new Headers({ 'Content-Type': '*' });
    let options = new RequestOptions({ headers: headers });
    return this.http.patch('my_url', ent).map((res: Response) => res.json());
  };

The error is:

Access to XMLHttpRequest at 'my_url' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

What can I to do? Thanks.

Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
rikg93
  • 1,101
  • 1
  • 11
  • 21
  • 1
    Possible duplicate of [Response to preflight request doesn't pass access control check](https://stackoverflow.com/questions/35588699/response-to-preflight-request-doesnt-pass-access-control-check) – paulsm4 Nov 12 '18 at 08:33
  • 1
    Wildcard for `Access-Control-Allow-Methods` is not yet supported in all browsers. Also that error message says it came back with a non-200 status, so you should see why it's erroring first – user184994 Nov 12 '18 at 08:38
  • @user184994 thank you, is there a different method instead Access-Control-Allow-Methods? – rikg93 Nov 12 '18 at 08:44
  • 1
    No, just pass the actual values, so `POST, GET, OPTIONS, PATCH` plus any others you care about – user184994 Nov 12 '18 at 08:46
  • Please refer to this post for answer nd how to solve this problem https://stackoverflow.com/questions/53528643/cross-origin-resource-sharing-cors-in-angular-or-angular-6-problem-while-you/53528644#53528644 – Ramesh Roddam Nov 28 '18 at 22:09
  • Does this answer your question? [Node JS - CORS Issue Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header](https://stackoverflow.com/questions/44736327/node-js-cors-issue-response-to-preflight-request-doesnt-pass-access-control-c) – Quentin Jan 08 '20 at 09:14
  • The answer section is slowly filling up with tips about how to break/disable CORS on your favorite server, which is not a very smart thing to do in general, and quite off-topic in the context of this question as well. Marked question as 'Protected'. – Andrey Tyukin Nov 15 '22 at 23:40

12 Answers12

56

There are two ways this can be handled:

  1. Temporary Front-End solution so you can test if your API integration is working:

Click on window -> type run and hit enter -> in the command window copy:

chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security

This will open a new "Chrome" window where you can work easily. This is a temporary solution. Every time you will have to work with this chrome window.

  1. Permanent solution:

In the backend code, the developer needs to add an annotation @Crossorigin right above the CRUD api call method.

Let me know if it works.

Bitly
  • 728
  • 2
  • 11
  • 22
10

Your error:

Access to XMLHttpRequest at 'my_url' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

My error:

Access to XMLHttpRequest at 'localhost:3000/api/todo' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

(Even though a bit different error but i'll answer anyway)

Now two questions here:

  1. How did i resolve my issue?

Ans. Putting 'http://' before api i used, means 'http://localhost:3000/api/todo'.

  1. What might've caused your error?

Ans. Can't say for sure but i dont see your api url instead it says 'my_url' (comparing both errors). I thik you may've passed string instead of variable.

I'll be happy if this helps anyone. Because this cost me almost 2hr and now it's midnight(almost).

Ankit
  • 181
  • 2
  • 15
7

I ran into the same issue even though my API was using cors and had the proper headers.

So for me, the issue was that I was making an insecure request. I was accessing my API over the http protocol, and that was causing the error.

I just changed from

http://api.example.com

to https protocol

https://api.example.com

and it fixed everything.


You can also create a simple proxy on your website to forward your request to the external site. For example, if you are trying to fetch some data from your website (my-website.com) to (another-website.com) and you make a POST request, you can have cors issues, but if you fetch the data from your own domain you will be good.

Here is how to create a simple proxy forwarding the request https://stackoverflow.com/a/20354642/7602110

So instead of making request to

POST https://api.example.com/event/create

You'll want to make the request to

POST https://my-website.com/api/event/create

I know that is some extra work, and sometimes you don't have the ability to do it, but that will definitely prevent you from having cors issues.

Abraham
  • 8,525
  • 5
  • 47
  • 53
6

use this in Node

    app.use(function (req, res, next) {
    //Enabling CORS
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, 
    Accept, x-client-key, x-client-token, x-client-secret, Authorization");
      next();
    });

And in angular the request is

 auth(login): Promise<any> {
 return new Promise((resolve, reject) => {
   this._http.post('url:3000/api/auth/login', { ...login })
     .subscribe((response: any) => {
       resolve(response);
     });
 });
}
Marcello B.
  • 4,177
  • 11
  • 45
  • 65
Sohail Ahmad
  • 7,309
  • 5
  • 27
  • 46
2

This problem is not on your frontend angular code it is related to backend,

Try below steps in your backend code :

1.npm install cors

2.put app.use(cors()) in main express route file.(enables all CORS requests)

may be it works for you.

reference link : https://expressjs.com/en/resources/middleware/cors.html

Savan2396
  • 112
  • 6
  • That's insufficient. See https://expressjs.com/en/resources/middleware/cors.html#enabling-cors-pre-flight – Quentin Jan 08 '20 at 09:13
2

I ran into the same issue some time ago. Below piece of code worked for me at the backend. The backend was written in express, node.

app.use(function (request, response, next) {
  response.header("Access-Control-Allow-Origin", "*");
  response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
Lin Du
  • 88,126
  • 95
  • 281
  • 483
Sambhaji Mane
  • 31
  • 1
  • 3
0

Adding proxy in package.json or bypassing with chrome extension is not really a solution. Just make sure you've enabled CORS in your server side before you have registered your routes. Given example is in Node.js and Express.js. Hope this helps!

app.use(cors())
app.use('/posts', postRoutes)
SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
0

for those who using ASP.net Core in the Backend

ADD this to program.cs

    builder.Services.AddCors(c =>
{
    c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyMethod().
     AllowAnyHeader());
});

app.UseCors("AllowOrigin");
0

In my case, the error was due to a missing '/' in service.ts. I was using Django for the backend.

getData(id: number): Observable<any> {
    return this.http.get<any>(`${this.APIurl}/data/${id}`);
}

So, I added a '/' at the end.

getData(id: number): Observable<any> {
    return this.http.get<any>(`${this.APIurl}/data/${id}/`);
}
-1

If you are using Tomcat try this: full documentation

 HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, "
                + "Access-Control-Request-Method, Access-Control-Request-Headers, Authorization");


        if ( request.getMethod().equals("OPTIONS") ) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }


        filterChain.doFilter(servletRequest, servletResponse);

Then in web.xml

<filter>
    <filter-name>cors</filter-name>
    <filter-class>classYouImplementTheCodeAbove</filter-class>
</filter>

<filter-mapping>
    <filter-name>cors</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

If you are using other go to https://enable-cors.org/server.html and search for it

FTello31
  • 51
  • 1
  • 10
-1

I had this issues and it was an syntax error in my action definition

 def self.rate_skills(params)
    data = {}
    data = where(individual_id: params[:individual_id]).select(:tool_name, :score)group('category').order(score: :desc).first(3)
    data 
  end

the issue is that I was the period before "group"

 def self.rate_skills(params)
    data = {}
    data = where(individual_id: params[:individual_id]).select(:tool_name, :score).group('category').order(score: :desc).first(3)
    data 
  end
CodeLife
  • 89
  • 6
-1

Firebase server specific issue:

In my case, I got the same below error while I am trying to access my URL.

Access to XMLHttpRequest at 'https://XXX-XXX-XXX-default-rtdb.asia-southeast1.firebasedatabase.app/' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

The code I used to send this request is below,

this.http
      .put(
        "https://XXX-XXX-XXX-default-rtdb.asia-southeast1.firebasedatabase.app/",
        data
      )
      .subscribe((response) => {
        console.log(response);
      });

I tried searching for a solution to my issue and couldn't find the exact solution. Anyhow I managed to figure out my mistake and here is my solution.

For my case, the error is due to invalid URL. I am supposed to send with a .json at the end of URL for firebase to consider it as a valid URL. (https://firebase.google.com/docs/database/rest/start)

After appending .json to my URL, my http requests got success.

this.http
      .put(
        "https://XXX-XXX-XXX-default-rtdb.asia-southeast1.firebasedatabase.app/.json",
        data
      )
      .subscribe((response) => {
        console.log(response);
      });