跨域请求被阻止

huangapple go评论76阅读模式
英文:

Cross-Origin Request Blocked

问题

所以我有一个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
    }
}

在我的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);

接收部分都正常工作。然而,我的响应被阻止了,给我以下消息:

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.

我尝试了很多其他方法,但无论如何都无法从服务器获取响应。然而,当我将Go的POST方法更改为GET,并通过浏览器访问页面时,我可以得到我想要的数据。我无法确定哪一方出错以及为什么:可能是Go不应该阻止这些请求,但也可能是我的JavaScript不合法。

英文:

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(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;)
    if r.Method == &quot;POST&quot; {

	    c := appengine.NewContext(r)

	    body, _ := ioutil.ReadAll(r.Body)

	    auth := string(body[:])
	    r.Body.Close()
	    q := datastore.NewQuery(&quot;Message&quot;).Order(&quot;-Date&quot;)

	    var msg []Message
	    key, err := q.GetAll(c, &amp;msg)

	    if err != nil {
	    	c.Errorf(&quot;fetching msg: %v&quot;, err)
	    	return
	    }

	    w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
	    jsonMsg, err := json.Marshal(msg)
	    msgstr := string(jsonMsg)
	    fmt.Fprint(w, msgstr)
	    return
    }
}

In my firefox OS app I use:

var message = &quot;content&quot;;

request = new XMLHttpRequest();
request.open(&#39;POST&#39;, &#39;http://localhost:8080/msgs&#39;, true);

request.onload = function () {
	if (request.status &gt;= 200 &amp;&amp; request.status &lt; 400) {
		// Success!
		data = JSON.parse(request.responseText);
		console.log(data);
	} else {
		// We reached our target server, but it returned an error
		console.log(&quot;server error&quot;);
	}
};

request.onerror = function () {
	// There was a connection error of some sort
	console.log(&quot;connection error&quot;);
};

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.

答案1

得分: 23

@Egidius,在创建XMLHttpRequest时,你应该使用以下代码:

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

mozSystem是什么?

mozSystem是一个布尔值。将此标志设置为true可以在不需要服务器使用CORS进行选择的情况下进行跨站点连接。需要设置mozAnon为true,即不能与发送cookie或其他用户凭据相结合。这仅适用于特权(经过审核的)应用程序;它不适用于在Firefox中加载的任意网页。

对清单的更改

在你的清单中,不要忘记在权限中包含以下行:

"permissions": {
       "systemXHR" : {},
}
英文:

@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:

&quot;permissions&quot;: {
       &quot;systemXHR&quot; : {},
}

答案2

得分: 1

你需要其他的头部信息,不仅仅是access-control-allow-origin。

如果你的请求中包含"Access-Control-Allow-Origin"头部信息,你必须将其复制到响应的头部信息中。如果没有,你必须检查"Origin"头部信息,并将其复制到响应中。如果你的请求既没有Access-Control-Allow-Origin头部信息,也没有Origin头部信息,你必须返回"*"。

你可以在这里阅读完整的解释:http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

以下是我用来编写跨域头部信息的函数:

func writeCrossDomainHeaders(w http.ResponseWriter, req *http.Request) {
    // 跨域头部信息
    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")
}

希望对你有帮助!

英文:

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[&quot;Access-Control-Request-Headers&quot;]; ok {
        w.Header().Set(&quot;Access-Control-Allow-Headers&quot;, acrh[0])
    }
    w.Header().Set(&quot;Access-Control-Allow-Credentials&quot;, &quot;True&quot;)
    if acao, ok := req.Header[&quot;Access-Control-Allow-Origin&quot;]; ok {
        w.Header().Set(&quot;Access-Control-Allow-Origin&quot;, acao[0])
    } else {
        if _, oko := req.Header[&quot;Origin&quot;]; oko {
            w.Header().Set(&quot;Access-Control-Allow-Origin&quot;, req.Header[&quot;Origin&quot;][0])
        } else {
            w.Header().Set(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;)
        }
    }
    w.Header().Set(&quot;Access-Control-Allow-Methods&quot;, &quot;GET, POST, PUT, DELETE&quot;)
    w.Header().Set(&quot;Connection&quot;, &quot;Close&quot;)

}

答案3

得分: 0

你必须将这段代码放在application.rb文件中:

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

You have to placed this code in application.rb

config.action_dispatch.default_headers = {
    	&#39;Access-Control-Allow-Origin&#39; =&gt; &#39;*&#39;,
    	&#39;Access-Control-Request-Method&#39; =&gt; %w{GET POST OPTIONS}.join(&quot;,&quot;)
}

huangapple
  • 本文由 发表于 2014年3月13日 04:38:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/22363268.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定