Has been blocked by CORS policy: Response to preflight request doesn’t pass access control check
Asked Answered
T

12

131

I have created trip server. It works fine and we are able to make POST request by Insomnia but when we make POST request by axios on our front-end, it sends an error:

has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.

Our request on axios:

let config = {
headers: {
  "Content-Type": "application/json",
  'Access-Control-Allow-Origin': '*',
  }
}

let data = {
  "id": 4
 }

 axios.post('http://196.121.147.69:9777/twirp/route.FRoute/GetLists', data, config)
   .then((res) => {
      console.log(res)
     })
    .catch((err) => {
      console.log(err)
   });
} 

My go file:

func setupResponse(w *http.ResponseWriter, req *http.Request) {
    (*w).Header().Set("Access-Control-Allow-Origin", "*")
    (*w).Header().Set("Access-Control-Allow-Methods", "POST,GET,OPTIONS, PUT, DELETE")

    (*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}


func WithUserAgent(base http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    ctx := r.Context()
    ua := r.Header.Get("Jwt")
    ctx = context.WithValue(ctx, "jwt", ua)

    r = r.WithContext(ctx)

    setupResponse(&w, r)
     base.ServeHTTP(w, r)
  })
}

const (
    host     = "localhost"
    port     = 5432
    user     = "postgres"
    password = "postgres"
    dbname   = "postgres"
)

func main() {

    psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
           "password=%s dbname=%s sslmode=disable",
               host, port, user, password, dbname)

    server := &s.Server{psqlInfo}

    twirpHandler := p.NewFinanceServiceServer(server, nil)

    wrap := WithUserAgent(twirpHandler)
      log.Fatalln(http.ListenAndServe(":9707", wrap))
}

As I said before on Insomnia it works great, but when we make an axios POST request, on browser's console following appears:

has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.

Tropho answered 14/11, 2018 at 10:52 Comment(4)
(*w).Header().Set("Access-Control-Allow-Origin", req.Header.Get("Origin"))Tatiana
@Tatiana does not work(Tropho
Please refer to this post for answer nd how to solve this problem #53529143Antipater
Hi Ramesh that link may not be the one you meant to paste it seems to be your response for a question relating to spring and the framework's particular CrossOrigin filters. For what it is worth, I think for this question if you are seeing the prefilght request but it is griping about not having ok status then from my experience you either have another error that is happening prior to the response, or OPTIONS is not an allowed verb.Countermine
G
78

I believe this is the simplest example:

header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")
header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")

You can also add a header for Access-Control-Max-Age and of course you can allow any headers and methods that you wish.

Finally you want to respond to the initial request:

if r.Method == "OPTIONS" {
    w.WriteHeader(http.StatusOK)
    return
}

Edit (June 2019): We now use gorilla for this. Their stuff is more actively maintained and they have been doing this for a really long time. Leaving the link to the old one, just in case.

Old Middleware Recommendation below: Of course it would probably be easier to just use middleware for this. I don't think I've used it, but this one seems to come highly recommended.

Gallardo answered 14/11, 2018 at 15:55 Comment(3)
Could you clarify what you did different from what the OP did? I already included what you said, and it doesn't work for me eitherJanessa
2023 update: The Gorilla project is no longer maintained.Peacemaker
2023 update: The Gorilla project is now actively maintained.Habit
S
51

This answer explains what's going on behind the scenes, and the basics of how to solve this problem in any language. For reference, see the MDN docs on this topic.

You are making a request for a URL from JavaScript running on one domain (say domain-a.com) to an API running on another domain (domain-b.com). When you do that, the browser has to ask domain-b.com if it's okay to allow requests from domain-a.com. It does that with an HTTP OPTIONS request. Then, in the response, the server on domain-b.com has to give (at least) the following HTTP headers that say "Yeah, that's okay":

HTTP/1.1 204 No Content                            // or 200 OK
Access-Control-Allow-Origin: https://domain-a.com  // or * for allowing anybody
Access-Control-Allow-Methods: POST, GET, OPTIONS   // What kind of methods are allowed
...                                                // other headers

If you're in Chrome, you can see what the response looks like by pressing F12 and going to the "Network" tab to see the response the server on domain-b.com is giving.

So, back to the bare minimum from @threeve's original answer:

header := w.Header()
header.Add("Access-Control-Allow-Origin", "*")

if r.Method == "OPTIONS" {
    w.WriteHeader(http.StatusOK)
    return
}

This will allow anybody from anywhere to access this data. The other headers he's included are necessary for other reasons, but these headers are the bare minimum to get past the CORS (Cross Origin Resource Sharing) requirements.

Spurious answered 3/10, 2019 at 13:14 Comment(3)
Actually, going to the Network tab will tell you nothing. The GET apparently succeeds even though the Console tab says that there is a cross-origin-header error. That's explained in this answer.Cowherd
I think you're looking at the OPTIONS request, not the GET request. There should be 2 requests in Chrome's Network tab for every GET request you do in your code.Spurious
This is a very in depth answer and manages to explain what usually is the cause of a CORS errorHemoglobin
B
24

The CORS issue should be fixed in the backend. Temporary workaround uses this option.

  1. Open the command prompt

  2. Navigate to chrome installed location OR enter cd "c:\Program Files (x86)\Google\Chrome\Application" OR cd "c:\Program Files\Google\Chrome\Application"

  3. Execute the command chrome.exe --disable-web-security --user-data-dir="c:/ChromeDevSession"

Using the above option, you can able to open new chrome without security. this chrome will not throw any cors issue.

enter image description here

Barbarous answered 12/11, 2020 at 16:23 Comment(5)
This is the only thing that worked for me. None of the other solutions worked.Massacre
This is the only thing that worked for me too! I prefer this solution as this suggests changes only on my DEV machine and I don't have to worry about server or other code changes. I was using IE for development before, where I can disable CORS settings there. Now I am left with only EDGE and CHROME browsers. I am not sure if we can turn off CORS settings in EDGE browser as well.Timelag
Thanks, I'm another where was the only solution to workEphod
Not sure, but in 2023 I also found this is the only solution that works for me.Lona
This is a good work around if you are just trying to do some local unit testing.Tatman
P
22

For anyone who haven't find a solution, and if you are using:

  1. AWS HTTP API Gateway;
  2. You are using ANY Method with Authentication for routes and lambda integration;
  3. You believe you have configured the CORS properly;

The error is because the browser is sending a preflight OPTIONS request to your route without Authentication header and thus cannot get CORS headers as response.

To fix this, I added another route for OPTIONS method without Authentication, and the lambda integration simply returns { statusCode: 200 };

Plenipotentiary answered 24/8, 2021 at 6:1 Comment(0)
I
10

Enable cross-origin requests in ASP.NET Web API click for more info

Enable CORS in the WebService app. First, add the CORS NuGet package. In Visual Studio, from the Tools menu, select NuGet Package Manager, then select Package Manager Console. In the Package Manager Console window, type the following command:

Install-Package Microsoft.AspNet.WebApi.Cors

This command installs the latest package and updates all dependencies, including the core Web API libraries. Use the -Version flag to target a specific version. The CORS package requires Web API 2.0 or later.

Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method:

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Next, add the [EnableCors] attribute to your controller/ controller methods

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

Enable Cross-Origin Requests (CORS) in ASP.NET Core

Interoffice answered 1/1, 2019 at 12:39 Comment(3)
op specified Go langGeerts
Go lang or axios not C#Sarad
+1 true, the OP specified Go lang, but I landed here and needed a solution for aspnet and this helped meEddieeddina
Q
5

Angular and Django Rest Framework.

I encountered similar error while making post request to my DRF api. It happened that all I was missing was trailing slash for endpoint.

Quadrangle answered 13/4, 2020 at 9:32 Comment(1)
I had just spent 1 hour with this (Vue.js + Django Rest Framework)Sayers
L
3

The provided solution here is correct. However, the same error can also occur from a user error, where your endpoint request method is NOT matching the method your using when making the request.

For example, the server endpoint is defined with "RequestMethod.PUT" while you are requesting the method as POST.

Loop answered 30/3, 2019 at 18:13 Comment(0)
C
3

In my case it was caused by a silly mistake when copying from other service but in incorrect place (order matters!)

Correct:

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UseCors(x => x
               .AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader());

            app.UseRouting();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

Incorrect:

      public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
      {
        app.UseRouting();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

        //had no effect
        app.UseCors(x => x
           .AllowAnyOrigin()
           .AllowAnyMethod()
           .AllowAnyHeader());
      }
Charlottecharlottenburg answered 25/7, 2022 at 23:3 Comment(0)
L
0

I encountered a similar problem, and even adding Header handling in PostHandler did not help. I used httpRouter (github.com/julienschmidt/httprouter):

handler := func(w http.ResponseWriter, r *http.Request, param httprouter.Params) {
  w.Header().Set("Access-Control-Allow-Origin", "*")
  w.Header().Set("Access-Control-Allow-Headers", "Accept, X-Requested-With, 
  Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
  // doPost 
}


httpRouter.POST(path, handler)

// Error: 
// Access to XMLHttpRequest at 'http://xxxx/postapi' 
//   from origin 'http://localhost:3000' has been blocked by CORS policy: 
//   Response to preflight request doesn't pass access control 
//   check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

The problem still exists.

Finally, the problem was resolved. The solution was:

// The Header handling also needs to be added in OPTIONS
handler := func(w http.ResponseWriter, r *http.Request, param httprouter.Params) {
  w.Header().Set("Access-Control-Allow-Origin", "*")
  w.Header().Set("Access-Control-Allow-Headers", "Accept, X-Requested-With, 
  Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
  if r.Method == "OPTIONS" {
    w.WriteHeader(http.StatusOK)
    return
  }
  // doPost ... 
}

httpRouter.OPTIONS(path, handler)
httpRouter.POST(path, handler)
Litigious answered 16/11, 2023 at 3:35 Comment(0)
G
-1

The only thing that worked for me was creating a new application in the IIS, mapping it to exactly the same physical path, and changing only the authentication to be Anonymous.

Georgiegeorgina answered 21/7, 2020 at 13:3 Comment(1)
Luckier than me. Nothing works, though the following SHOULD work!!! app.UseCors(builder => { builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); });Albino
A
-1

For anyone looking at this and had no result with adding the Access-Control-Allow-Origin try also adding the Access-Control-Allow-Headers. May safe somebody from a headache.

Antimonic answered 25/11, 2020 at 14:59 Comment(0)
D
-1

install Cors dependency in the node server and all below code in your node server.

const cors = require("cors");
app.use(
cors({
  origin: "http://localhost:3000",
  })
);
Determine answered 20/8, 2023 at 4:32 Comment(1)
The question isn't about express.Just

© 2022 - 2024 — McMap. All rights reserved.