Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 671
GGG Avatar asked Nov 14 '18 10:11

GGG


People also ask

How do you solve CORS policy no Access-Control allow origin?

If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.

How do I fix access to XMLHttpRequest at origin has blocked by CORS policy?

How Access to XMLHttpRequest has been blocked by CORS policy Redirect is not allowed for a preflight request only one route Error Occurs ? Just Disable CORS policy security. Go to google extension and search for Allow-Control-Allow-Origin. Now add it to chrome and enable.

What is Access-Control allow methods?

Access-Control-Allow-Methods is a header request that allows one or more HTTP methods when accessing a resource when responding to a preflight request. Access-Control-Allow-Methods shows permitted HTTP methods while accessing resources.


2 Answers

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.

like image 194
trey-jones Avatar answered Sep 24 '22 13:09

trey-jones


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.

like image 40
Ryan Shillington Avatar answered Sep 24 '22 13:09

Ryan Shillington