CORS机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。 以下是可用于CORS配置的标头列表
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
Access-Control-Max-Age
CORS配置位于目标Web应用程序的服务器端。 例如:我们的应用程序在本地从google.com中提取数据,然后CORS配置位于google.com;如果我们收到CORS错误,则无法完成任何其他操作,因为CORS应用程序目标由google.com上的人员控制。
练习时间:
创建一个新项目。这个简单的应用程序将在http//localhost:9000/
上运行,然后我们将尝试从其他域访问它.
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "https://www.google.com")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token")
if r.Method == "OPTIONS" {
w.Write([]byte("allowed"))
return
}
w.Write([]byte("hello"))
})
log.Println("Starting app at :9000")
http.ListenAndServe(":9000", nil)
}
上面的代码表示允许从https://www.google.com
发送的请求进入;我们选择了谷歌域名,因为测试将从那里完成,请求的目标是http://localhost:9000/
我们模拟是从google.com 访问 本地主机Web应用localhost:9000
(使用Chrome的开发人员工具从浏览器执行请求)。不是通过localhost:9000
访问google.com
,不要理解为颠倒。
再次说明,localhost:9000是受,google.com是攻。够形象了吧。
Access-Control-Allow-Methods
标头确定允许哪些HTTP方法(使用逗号分隔符输入)
Access-Control-Allow-Headers
标头确定请求中允许哪些标头密钥。
好的,我们可以测试了。
首先,请确保安装了Google Chrome;
其次,你可以爬墙;
然后安装jQuery Injector扩展。
打开https://www.google.com
然后注入jQuery。通过强制注入jQuery然后从谷歌网站我们可以使用jQuery。
打开Chrome开发者工具,切换到Console标签页。输入以下:
$.ajax({
url: "http://localhost:9000/index",
})
ok,结果如下图
我切换到hk代理,打开google.com.hk,在执行操作就不能访问。因为
Access-Control-Allow-Origin
我们只设置了www.google.com
.如果我们需要能访问呢?以下就可以搞定允许多个主机来访问:
http.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin",
"https://www.google.com, https://www.google.com.hk")
当然也可以不设防,赤果果
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
##第三方CORS库来稍微优雅点解决问题
$ go get github.com/rs/cors
利用中间件,代码优雅
package main
import (
"net/http"
"github.com/labstack/echo"
"github.com/rs/cors"
)
func main() {
e := echo.New()
corsMiddleware := cors.New(cors.Options{
AllowedOrigins: []string{"https://www.google.com.hk", "https://www.google.com"},
AllowedMethods: []string{"OPTIONS", "GET", "POST", "PUT"},
AllowedHeaders: []string{"Content-Type", "X-CSRF-Token"},
Debug: true,
})
e.Use(echo.WrapMiddleware(corsMiddleware.Handler))
e.GET("/index", func(c echo.Context) error {
return c.String(http.StatusOK, "hello")
})
e.Logger.Fatal(e.Start(":9000"))
}
搞定。
最后修改于 2019-08-17