GO — 提供跨域請求代理服務

單頁應用中,異步請求數據會受到同源政策限制。前端

只有當 協議端口、和 域名都相同的頁面,則兩個頁面具備相同的源。只要網站的 協議名protocol、 主機host、 端口號port 這三個中的任意一個不一樣,網站間的數據請求與傳輸便構成了跨域調用,會受到 同源策略的限制。

不單單是傳統的ajax,基於promise的axios和fetch也會受到限制。解決方法有不少,這裏簡述一下使用golang搭建一個簡單的代理服務。vue

proxy

用代理實現跨域請求的原理是ios

DomainA客戶端(瀏覽器) ==> DomainA服務器 ==> DomainB服務器 ==> DomainA客戶端(瀏覽器)git

在頁面的同源瀏覽器搭建一個代理服務,頁面請求數據發至同源服務器後,由同源服務器轉發到目標服務器,同時等待響應並將響應轉發回頁面。github

實際上,在一些前端框架中,如vue.js,提供了簡易的代理服務以供測試。在服務端採用相同的配置,能夠很是方便的從開發環境轉向生產環境。golang

httprouter

httprouter是基於golang提供的http包之上封裝的很是輕便的http框架。ajax

HttpRouter is a lightweight high performance HTTP request router (also called multiplexer or just mux for short) for Go.

使用httprouter能夠很是方便的解析url,添加handler。shell

go get github.com/julienschmidt/httprouter

主函數內添加要代理的地址和處理函數。axios

func main() {
    router := httprouter.New()
    router.GET("/", index)
    //以post方式訪問/github爲前綴的url時,完整的url會轉化爲參數傳入函數
    router.POST("/github/*proxyPath", proxy) 
    log.Fatal(http.ListenAndServe(serverPort, router))
}
func proxy(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
   // /github -> remote
   remote := "https://github.com"
   // 獲取完整url
   u := remote + ps.ByName("proxyPath")
   log.Println(r.URL,"=>",u)
   // 以現有的request建立新的request
   req,err := http.NewRequest(r.Method, u , r.Body) /* method url body */
   req.Header = r.Header /* header */
   client := http.DefaultClient
   // 發起新的請求
   res, err := client.Do(req)
   if err != nil {
      w.WriteHeader(404)
      fmt.Fprint(w, err)
      return
   }
   // 獲取新的body
   bodyRes,err:=ioutil.ReadAll(res.Body)
   if err!=nil{
      w.WriteHeader(404)
      fmt.Fprint(w, err)
      return
   }
   // 設置新的header
   for k, vs := range res.Header {
      for _, v := range vs {
         w.Header().Add(k,v)
      }
   }
   // 設置新的cookie
   for _, value := range res.Request.Cookies() {
      w.Header().Add(value.Name,value.Value)
   }
   // 寫入狀態
   w.WriteHeader(res.StatusCode)
   w.Write(bodyRes)
}

特別注意:寫出時必須先設置header再寫出狀態碼和body跨域

以post的方式訪問咱們的代理地址

image

image

查看log

2018/02/22 11:33:07 /github/login/oauth/access_token => https://github.com/login/oauth/access_token
相關文章
相關標籤/搜索