go 原生http web 服務(wù)跨域restful api的寫法介紹
錯(cuò)誤寫法
func main() {
openHttpListen()
}
func openHttpListen() {
http.HandleFunc("/", receiveClientRequest)
fmt.Println("go server start running...")
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func receiveClientRequest(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") //允許訪問所有域
w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的類型
w.Header().Set("content-type", "application/json") //返回?cái)?shù)據(jù)格式是json
r.ParseForm()
fmt.Println("收到客戶端請求: ", r.Form)
這樣還是會(huì)報(bào)錯(cuò):
說沒有得到響應(yīng)跨域的頭,chrome的network中確實(shí)沒有響應(yīng)Access-Control-Allow-Origin
正確寫法:
func LDNS(w http.ResponseWriter, req *http.Request) {
if origin := req.Header.Get("Origin"); 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 req.Method == "OPTIONS" {
return
}
// 響應(yīng)http code
w.WriteHeader(200)
query := strings.Split(req.Host, ".")
value, err := ldns.RAMDBMgr.Get(query[0])
fmt.Println("Access-Control-Allow-Origin", "*")
if err != nil {
io.WriteString(w, `{"message": ""}`)
return
}
io.WriteString(w, value)
}
補(bǔ)充:go http允許跨域
1.創(chuàng)建中間件
import (
"github.com/gin-gonic/gin"
"net/http"
)
// 跨域中間件
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
if origin != "" {
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
c.Header("Access-Control-Allow-Credentials", "false")
c.Set("content-type", "application/json")
}
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
c.Next()
}
}
2.在route中引用中間件
router := gin.Default() // 要在路由組之前全局使用「跨域中間件」, 否則OPTIONS會(huì)返回404 router.Use(Cors())
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
淺析go中的map數(shù)據(jù)結(jié)構(gòu)字典
golang中的map是一種數(shù)據(jù)類型,將鍵與值綁定到一起,底層是用哈希表實(shí)現(xiàn)的,可以快速的通過鍵找到對應(yīng)的值。這篇文章主要介紹了go中的數(shù)據(jù)結(jié)構(gòu)字典-map,需要的朋友可以參考下2019-11-11
一文教你如何快速學(xué)會(huì)Go的切片和數(shù)組數(shù)據(jù)類型
數(shù)組是屬于同一類型的元素的集合。切片是數(shù)組頂部的方便、靈活且功能強(qiáng)大的包裝器。本文就來和大家聊聊Go中切片和數(shù)組的使用,需要的可以參考一下2023-03-03
golang中l(wèi)og包自定義輸出日志格式與寫入到文件
這篇文章主要給大家介紹了關(guān)于golang中l(wèi)og包自定義輸出日志格式與寫入到文件的相關(guān)資料,日志輸出在任何項(xiàng)目中都極其重要,是有助于后續(xù)我們排查解決程序BUG,需要的朋友可以參考下2023-06-06
Golang?channel關(guān)閉后是否可以讀取剩余的數(shù)據(jù)詳解
這篇文章主要介紹了Golang?channel關(guān)閉后是否可以讀取剩余的數(shù)據(jù),文章通過一個(gè)測試?yán)咏o大家詳細(xì)的介紹了是否可以讀取剩余的數(shù)據(jù),需要的朋友可以參考下2023-09-09
深入解析Go語言的io.ioutil標(biāo)準(zhǔn)庫使用
這篇文章主要介紹了Go語言的io.ioutil標(biāo)準(zhǔn)庫使用,是Golang入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10

