Cross-Origin Request Blocked

170,176

Solution 1

@Egidius, when creating an XMLHttpRequest, you should use

var xhr = new XMLHttpRequest({mozSystem: true});

What is mozSystem?

mozSystem Boolean: Setting this flag to true allows making cross-site connections without requiring the server to opt-in using CORS. Requires setting mozAnon: true, i.e. this can't be combined with sending cookies or other user credentials. This only works in privileged (reviewed) apps; it does not work on arbitrary webpages loaded in Firefox.

Changes to your Manifest

On your manifest, do not forget to include this line on your permissions:

"permissions": {
       "systemXHR" : {},
}

Solution 2

You need other headers, not only access-control-allow-origin. If your request have the "Access-Control-Allow-Origin" header, you must copy it into the response headers, If doesn't, you must check the "Origin" header and copy it into the response. If your request doesn't have Access-Control-Allow-Origin not Origin headers, you must return "*".

You can read the complete explanation here: http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

and this is the function I'm using to write cross domain headers:

func writeCrossDomainHeaders(w http.ResponseWriter, req *http.Request) {
    // Cross domain headers
    if acrh, ok := req.Header["Access-Control-Request-Headers"]; ok {
        w.Header().Set("Access-Control-Allow-Headers", acrh[0])
    }
    w.Header().Set("Access-Control-Allow-Credentials", "True")
    if acao, ok := req.Header["Access-Control-Allow-Origin"]; ok {
        w.Header().Set("Access-Control-Allow-Origin", acao[0])
    } else {
        if _, oko := req.Header["Origin"]; oko {
            w.Header().Set("Access-Control-Allow-Origin", req.Header["Origin"][0])
        } else {
            w.Header().Set("Access-Control-Allow-Origin", "*")
        }
    }
    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
    w.Header().Set("Connection", "Close")

}
Share:
170,176

Related videos on Youtube

Dani
Author by

Dani

Updated on June 10, 2020

Comments

  • Dani
    Dani almost 4 years

    So I've got this Go http handler that stores some POST content into the datastore and retrieves some other info in response. On the back-end I use:

    func handleMessageQueue(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        if r.Method == "POST" {
    
            c := appengine.NewContext(r)
    
            body, _ := ioutil.ReadAll(r.Body)
    
            auth := string(body[:])
            r.Body.Close()
            q := datastore.NewQuery("Message").Order("-Date")
    
            var msg []Message
            key, err := q.GetAll(c, &msg)
    
            if err != nil {
                c.Errorf("fetching msg: %v", err)
                return
            }
    
            w.Header().Set("Content-Type", "application/json")
            jsonMsg, err := json.Marshal(msg)
            msgstr := string(jsonMsg)
            fmt.Fprint(w, msgstr)
            return
        }
    }
    

    In my firefox OS app I use:

    var message = "content";
    
    request = new XMLHttpRequest();
    request.open('POST', 'http://localhost:8080/msgs', true);
    
    request.onload = function () {
        if (request.status >= 200 && request.status < 400) {
            // Success!
            data = JSON.parse(request.responseText);
            console.log(data);
        } else {
            // We reached our target server, but it returned an error
            console.log("server error");
        }
    };
    
    request.onerror = function () {
        // There was a connection error of some sort
        console.log("connection error");
    };
    
    request.send(message);
    

    The incoming part all works along and such. However, my response is getting blocked. Giving me the following message:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/msgs. This can be fixed by moving the resource to the same domain or enabling CORS.
    

    I tried a lot of other things but there is no way I can just get a response from the server. However when I change my Go POST method into GET and access the page through the browser I get the data that I want so bad. I can't really decide which side goes wrong and why: it might be that Go shouldn't block these kinds of requests, but it also might be that my javascript is illegal.

    • Not_a_Golfer
      Not_a_Golfer about 10 years
      Seems to me (I'm not writing this as an answer since I'm not sure) that you're not setting the content type on the request. From Mozilla's TFM on the subject: If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain
  • Dani
    Dani about 10 years
    How much I'd like to confirm your answer; I just can't seem to get it working. Is there some way I can see what headers my Firefox OS javascript is sending? if I console.log(request) I get: [object DeadObject]. The Golang side prints the following w.Header(): map[Access-Control-Allow-Credentials:[True] Access-Control-Allow-Origin:[app://d8c37181-3d41-5c40-8a1e-3‌​abfa8cb3955] Access-Control-Allow-Methods:[GET, POST]]
  • Dani
    Dani about 10 years
    typical; I should've rtfm better. I tried the mozSystem xhr arg before, but I skipped at the manifest part because it wasn't valid JSON. Now I've just added some nonsense and my error is gone. Even though I still won't get a response I think this fixed it, must be some of my changes in attempt to fix the CORS error that messes this part up right now. Thanks a lot!
  • msaad
    msaad about 10 years
    You're more than welcome Egidius. Cors can be nonsense sometimes, but It's good to be defaulted as false because many developers don't understand the risks of allowing such. I'm glad I could help.
  • Karl
    Karl about 10 years
    I use firebug. It lets you see the whole requestand response headers and body. Now, why the origins says: app://?
  • Karl
    Karl about 10 years
    Another thing. Are you answering the OPTIONS method in your backend? All cross domain requests first calls the backend with the OPTION method and if that method responds with the headers I sent in my previous answer, then the real request is made. For example: if you execute a cross domain POST, your browser will do an OPTIONS request to the backend and if the answer is correct (the backend answer the correct cors headers) then the real POST will be executed.
  • Karl
    Karl about 10 years
    I'm using Gorilla/Mux and this is how I handle the OPTIONS requets: r := mux.NewRouter() r.StrictSlash(true) r.PathPrefix("/").Methods("OPTIONS").HandlerFunc(writeCrossD‌​omainHeaders) r.Handle("/widget", context.Handler(blah_blah_blah)).Methods("GET")
  • Dani
    Dani about 10 years
    Hi Carl, ah, Firebug; I should've known. The origin says app:// because it's a firefox OS app I'm running. It appears that this particular "detail" was causing my problem as stated above by @msaad. I came across Gorilla a couple of times in my search for Golang answers, but at that point I didn't see why I should use it. But I guess I should take a second look; your way of handling the OPTIONS request seems more convenient
  • R Claven
    R Claven over 9 years
    Thank you for this info but do you have any sources? Additional info? Its not working for me . . .
  • msaad
    msaad over 9 years
    @RClaven, sure. This developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest might help you. Also, make sure you're not hitting CORS problems intead of permission problems.
  • jub0bs
    jub0bs over 2 years
    The true value in the ACAC response header must be lowercase or compliant browsers will reject it.