跨域问题的本质跨域问题主要来源于浏览器的安全策略——同源策略(Same-originpolicy)。这个策略限制了来自不同源的“写”操作(如XMLHttpRequest请求)。当一个网页尝试从不同于当前文档域名的另一个域名获取资源时,就会遇到跨域问题。CORS简介CORS(Cross-Ori
跨域问题主要来源于浏览器的安全策略——同源策略(Same-origin policy)。这个策略限制了来自不同源的“写”操作(如XMLHttpRequest请求)。当一个网页尝试从不同于当前文档域名的另一个域名获取资源时,就会遇到跨域问题。
CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种机制,它使用额外的HTTP头部让浏览器与服务器进行沟通,从而决定一个网页是否可以被允许访问另一个来源的资源。
Go语言本身并没有内置对CORS的支持,但可以通过自定义中间件来轻松实现。下面我们将详细介绍如何编写这样一个中间件。
基本的HTTP服务设置 首先,我们需要创建一个基本的HTTP服务作为基础。
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})
http.ListenAndServe(":8080", nil)
}
添加CORS支持 接下来,我们添加一个简单的CORS中间件。
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") // 允许任何源访问
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
if r.Method == "OPTIONS" {
return
}
next.ServeHTTP(w, r)
})
}
然后修改主函数以使用这个中间件:
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})
handler := corsMiddleware(http.DefaultServeMux)
http.Handle("/", handler)
http.ListenAndServe(":8080", nil)
}
测试CORS功能 为了验证我们的CORS配置是否有效,可以使用Postman或者编写一个简单的前端页面来进行测试。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CORS Test</title>
</head>
<body>
<button id="fetchData">Fetch Data</button>
<script>
document.getElementById('fetchData').addEventListener('click', function() {
fetch('http://localhost:8080', { method: 'GET' })
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
});
</script>
</body>
</html>
在实际应用中,CORS配置可能需要更加细致和灵活。以下是一些进阶配置的例子。
限制特定域名访问 如果希望限制CORS仅对某些特定域名开放,可以在中间件中加入相应的逻辑。
func corsMiddleware(allowedOrigins []string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var origin string
for _, o := range allowedOrigins {
if r.Header.Get("Origin") == o {
origin = o
break
}
}
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
if r.Method == "OPTIONS" {
return
}
} else {
http.Error(w, "Forbidden", http.StatusForbidden)
return... 如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!