Golang解决跨域问题【OPTIONS预处理请求】

Golang解决跨域问题

前置知识:跨域问题产生条件及原因

跨域是是因为浏览器的同源策略限制,是浏览器的一种安全机制,服务端之间是不存在跨域的。

所谓同源指的是两个页面具有相同的协议、主机和端口,三者有任一不相同即会产生跨域。

解决

1 设置请求头

//1. 允许所有来源:不限IP
//2. 允许所有方法
//3. 允许请求头
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Accept,yi-token")

2 处理预处理请求

w3c规范要求,当浏览器判定请求为复杂请求时,会在真实携带数据发送请求前,多一个预处理请求:

  1. 请求方法不是get head post
  2. post 的content-type不是application/x-www-form-urlencode,multipart/form-data,text/plain [也就是把content-type设置成"application/json"]
  3. 请求设置了自定义的header字段: 比如业务需求,传一个字段,方面后端获取,不需要每个接口都传
if r.Method == "OPTIONS" {
    
    
	//handle the preflight request
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept,yi-token")
	w.WriteHeader(http.StatusOK)
	return
}

3 允许自定义请求头

当我们有自定义请求头(如token)需要传递时,也需要在代码中设置

//允许yi-token在请求头中传递
w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Accept,yi-token")

4 完整代码

package main

import (
	"github.com/aobco/log"
	"net/http"
	"time"
)

/*
	后端解决跨域问题
*/

func main() {
    
    
	mux := http.NewServeMux()
	mux.Handle("/cros/smoke", interceptor(http.HandlerFunc(smoke)))
	http.ListenAndServe(":8080", mux)
}

func smoke(w http.ResponseWriter, r *http.Request) {
    
    
	now := time.Now().String()
	_, err := w.Write([]byte(now))
	if err != nil {
    
    
		log.Errorf("%v", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	return
}

//拦截器
func interceptor(next http.Handler) http.Handler {
    
    
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    
    
		//resolve the cross origin[解决预请求]
		//w3c规范要求,当浏览器判定请求为复杂请求时,会在真实携带数据发送请求前,多一个预处理请求:
		//1. 请求方法不是get head post
		//2. post 的content-type不是application/x-www-form-urlencode,multipart/form-data,text/plain [也就是把content-type设置成"application/json"]
		//3. 请求设置了自定义的header字段: 比如业务需求,传一个字段,方面后端获取,不需要每个接口都传
		if r.Method == "OPTIONS" {
    
    
			//handle the preflight request
			w.Header().Set("Access-Control-Allow-Origin", "*")
			w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept,yi-token")
			w.WriteHeader(http.StatusOK)
			return
		}
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Accept,yi-token")
		next.ServeHTTP(w, r)
	})
}

猜你喜欢

转载自blog.csdn.net/weixin_45565886/article/details/135308855