2014-03-12 195 views
19

所以我已经有了这个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是非法的。

+0

对我来说似乎(我不写这个作为答案,因为我不确定)你没有设置请求上的内容类型。从Mozilla的TFM就这个问题:'如果使用POST向服务器发送数据,则使用HTTP POST请求发送到服务器的数据的内容类型是application/x-www-form-urlencoded,multipart /表单数据或文本/纯文本' –

回答

19

@Egidius,创建一个XMLHttpRequest时,你应该使用

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

什么是mozSystem?

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

更改您的清单

在您的清单,不要忘了,包括您的权限这一行:

"permissions": { 
     "systemXHR" : {}, 
} 
+0

典型;我应该更好一些。我之前尝试过mozSystem xhr arg,但是我跳过了清单部分,因为它不是有效的JSON。现在我刚刚添加了一些废话,我的错误消失了。尽管我仍然不会得到任何回应,但我认为这样做可以解决这个问题,我必须对其中的一些更改进行修正,试图修复CORS错误,以便立即纠正这部分内容。非常感谢! – Dani

+1

你不仅仅是欢迎Egidius。 Cors有时候可能是无稽之谈,但很多人认为虚假是错误的,因为许多开发人员不了解允许这样做的风险。我很高兴能够提供帮助。 – msaad

+0

谢谢你的这个信息,但你有什么消息来源?附加信息?它不适合我。 。 。 –

2

您需要其他标题,而​​不仅仅是访问控制允许来源。 如果您的请求具有“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) { 
    // 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") 

} 
+0

多少我想确认您的答案;我似乎无法得到它的工作。有什么方法可以查看我的Firefox OS javascript发送了什么标题?如果我console.log(请求)我得到:[object DeadObject]。 Golang侧打印以下w.Header():map [A​​ccess-Control-Allow-Credentials:[True] Access-Control-Allow-Origin:[app:// d8c37181-3d41-5c40-8a1e-3abfa8cb3955] Access-控制 - 允许 - 方法:[GET,POST]] – Dani

+0

我使用萤火虫。它可以让你看到整个请求和响应标题和正文。 现在,为什么起源说:app://? – Karl

+0

另一件事。你是否回答你后端的OPTIONS方法? 所有跨域请求首先使用OPTION方法调用后端,并且如果该方法使用我在先前答案中发送的标头进行响应,则会发出真正的请求。 例如:如果您执行跨域POST,您的浏览器将对后端执行OPTIONS请求,如果答案正确(后端回答正确的cors标头),那么将会执行真正的POST。 – Karl

10
ERROR : Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at the url. This can be fixed by moving the resource to the same domain or enabling CORS. 

解决方案:

我找到解决方案cross-origin request bolcked "solved"

如果您正在使用的网络项目,并希望从不同的站点获取数据, 有时你会得到这样的错误类型 ,那么你必须使用使用的htaccess的服务服务器的根文件夹(不接收服务器文件)

更新代码

<FilesMatch "\.(php)$"> 
    <IfModule mod_headers.c> 
    Header set Access-Control-Allow-Origin "*" 
    </IfModule> 
</FilesMatch> 

如果你是那么一个WordPress的开发者下面的代码更新:

# BEGIN WordPress 
<IfModule mod_rewrite.c> 
RewriteEngine On 
RewriteBase/
RewriteRule ^index\.php$ - [L] 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule . /index.php [L] 
</IfModule> 

<FilesMatch "\.(php)$"> 
    <IfModule mod_headers.c> 
    Header set Access-Control-Allow-Origin "*" 
    </IfModule> 
</FilesMatch> 

# END WordPress 

谢谢:)快乐编码:

+0

在wordpress中为我工作。 – Sajal

+0

哦,我很高兴我能给你100 Ups,但没有那么多声誉,但是,这解决了我3天的问题,非常感谢你。 –

+0

请记住,通过允许*,您可能会将您的网站打开为恶意或滥用请求。 –