Hi I'm implementing rest apis and for that I want to allow cross origin requests to be served.
What I am currently doing:
Go-server code on AWS:
func (c *UserController) Login(w http.ResponseWriter, r *http.Request, ctx *rack.Context) { w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") ... ... c.render.Json(w,rsp, http.StatusOK) return }
Ajax code on localhost:
<script> $( document ).ready(function() { console.log( "ready!" ); $.ajax({ url: 'http://ip:8080/login', crossDomain: true, //set as a cross domain requests withCredentials:false, type: 'post', success: function (data) { alert("Data " + data); }, }); });
I am getting the following error on browser console: XMLHttpRequest cannot load http://ip:8080/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. The response had HTTP status code 422.
I tried adding preflight options:
func corsRoute(app *app.App) { allowedHeaders := "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization,X-CSRF-Token" f := func(w http.ResponseWriter, r *http.Request) { if origin := r.Header.Get("Origin"); origin != "" { 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", allowedHeaders) w.Header().Set("Access-Control-Expose-Headers", "Authorization") } return } app.Router.Options("/*p", f, publicRouteConstraint) }
But it is not working.
What can be done to fix it.
Scope Rules for [EnableCors] You can enable CORS per action, per controller, or globally for all Web API controllers in your application. To enable CORS for a single action, set the [EnableCors] attribute on the action method. The following example enables CORS for the GetItem method only.
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.
Cross-origin resource sharing (CORS) is a mechanism implemented in web browsers to allow or deny requests coming from a different domain to your web app. With CORS, web browsers and web servers agree on a standard protocol to understand whether the resources are allowed to access or not.
Cross-origin resource sharing (CORS) is a browser security feature that restricts cross-origin HTTP requests that are initiated from scripts running in the browser. If your REST API's resources receive non-simple cross-origin HTTP requests, you need to enable CORS support.
CORS in Golang. Dealing Ajax Cross Origin. CORS stands for Cross Origin Resource Sharing, and consists of a handshake of cryptic headers (usually) from a browser to a web api server. The handshake isn’t well known, and usually people just “enable” cors in the web server, and all is right with the world again.
CORS stands for Cross Origin Resource Sharing, and consists of a handshake of cryptic headers (usually) from a browser to a web api server. The handshake isn’t well known, and usually people just “enable” cors in the web server, and all is right with the world again. Here is how the handshake breaks down:
CORS stands for Cross Origin Resource Sharing, and consists of a handshake of cryptic headers (usually) from a browser to a web api server. The handshake isn’t well known, and usually people just “enable” cors in the web server, and all is right with the world again.
For allowing CORS your server should to catch all Preflight request that's browser sends before real query with OPTIONS method to the same path.
I use gorilla/mux
package to build Go RESTful API server, and client use JavaScript Request can work,
My Go Server runs at localhost:9091
, and the Server code:
router := mux.NewRouter() //api route is /people, //Methods("GET", "OPTIONS") means it support GET, OPTIONS router.HandleFunc("/people", GetPeopleAPI).Methods("GET", "OPTIONS") log.Fatal(http.ListenAndServe(":9091", router))
I find giving OPTIONS
here is important, otherwise error will occur:
OPTIONS http://localhost:9091/people 405 (Method Not Allowed)
Failed to load http://localhost:9091/people: 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:9092' is therefore not allowed access. The response had HTTP status code 405.
after allow OPTIONS
it works great. I get the idea from This Article.
Besides, MDN CORS doc mention:
Additionally, for HTTP request methods that can cause side-effects on server's data, the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method.
Following is the api GetPeopleAPI method, note in the method I give comment //Allow CORS here By * or specific origin, I have another similar answer explaining the concept of CORS Here:
func GetPeopleAPI(w http.ResponseWriter, r *http.Request) { //Allow CORS here By * or specific origin w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "Content-Type") // return "OKOK" json.NewEncoder(w).Encode("OKOK") }
In the client, I use html with javascript on localhost:9092
, and javascript will send request to server from localhost:9092
function GetPeople() { try { var xhttp = new XMLHttpRequest(); xhttp.open("GET", "http://localhost:9091/people", false); xhttp.setRequestHeader("Content-type", "text/html"); xhttp.send(); var response = JSON.parse(xhttp.response); alert(xhttp.response); } catch (error) { alert(error.message); } }
and the request can successfully get response "OKOK"
.
You can also check response/request header information by tools like Fiddler
.
Thanks for the clue - it's all in the header! I use only these golang headers on the server side:
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Access-Control-Allow-Origin", "*")
Now works with this JQuery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"> </script> <script> $.ajax({ type: 'GET', url: 'https://www.XXXXXXX.org/QueryUserID?u=juXXXXny&p=blXXXXXne', crossDomain: true, dataType: 'text', success: function(responseData, textStatus, jqXHR) { alert(responseData); }, error: function (responseData, textStatus, errorThrown) { alert('POST failed.'); } }); </script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With