清风徐来
Michael's Blog
Demo 学 Echo Part12 CORS 跨域资源共享和Request 预检

请输入图片描述

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,结果如下图 cors_from_google_to_localhost.png 我切换到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