ajax 跨域请求被阻止

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22363268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:24:23  来源:igfitidea点击:

Cross-Origin Request Blocked

ajaxgoogle-app-enginegocorsfirefox-os

提问by Dani

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:

所以我有这个 Go http 处理程序,它将一些 POST 内容存储到数据存储中并检索一些其他信息作为响应。在后端我使用:

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:

在我的 Firefox OS 应用程序中,我使用:

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.

我尝试了很多其他事情,但我无法从服务器获得响应。但是,当我将 Go POST 方法更改为 GET 并通过浏览器访问页面时,我得到了我想要的数据。我真的不能决定哪一方出错以及为什么:可能是 Go 不应该阻止这些类型的请求,但也可能是我的 javascript 是非法的。

采纳答案by msaad

@Egidius, when creating an XMLHttpRequest, you should use

@Egidius,在创建 XMLHttpRequest 时,您应该使用

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

What is mozSystem?

moz系统是什么?

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.

mozSystem Boolean:将此标志设置为 true 允许进行跨站点连接,而无需服务器选择使用 CORS。需要设置 mozAnon: true,即这不能与发送 cookie 或其他用户凭据结合使用。这仅适用于特权(已审核)应用程序;它不适用于 Firefox 中加载的任意网页。

Changes to your Manifest

对您的清单的更改

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

在您的清单中,不要忘记在您的权限中包含这一行:

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

回答by Karl

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 "*".

您需要其他标头,而不仅仅是 access-control-allow-origin。如果您的请求具有“Access-Control-Allow-Origin”标头,则必须将其复制到响应标头中,如果没有,则必须检查“Origin”标头并将其复制到响应中。如果您的请求没有 Access-Control-Allow-Origin 而不是 Origin 标头,则必须返回“*”。

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

你可以在这里阅读完整的解释: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")

}

回答by sivamani

You have to placed this code in application.rb

您必须将此代码放在 application.rb 中

config.action_dispatch.default_headers = {
        'Access-Control-Allow-Origin' => '*',
        'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",")
}