2014-03-12 242 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

請記住,通過允許*,您可能會將您的網站打開爲惡意或濫用請求。 –