如何将 javascript 热重载集成到带有 https 的 golang 路由中以进行开发?

我想为 golang + svelte 设置下一个简单的开发设置


前端部分

$ npx degit sveltejs/template frontend

$ yarn

$ yarn dev # it start the frontend env on http://localhost:5000

所以我在http://localhost:5000上有一个正在运行的前端


后端部分

使用 https on :443 go net/http 路由器,使用 mkcert 创建自签名证书

https://localhost/hello -> go handlers for show normal go handlers

https://localhost/ -> 反向代理http://localhost:5000

package main


import (

   "bytes"

   "io/ioutil"

   "log"

   "net/http"

   "net/http/httputil"

   "net/url"

   "strconv"

)


func newDirector(origin url.URL) func(*http.Request) {

   return func(req *http.Request) {

       req.Header.Add("X-Forwarded-Host", req.Host)

       req.Header.Add("X-Origin-Host", origin.Host)

       req.URL.Scheme = "http"

       req.URL.Host = origin.Host

   }

}


func newReplacer(orig, replace string) func(resp *http.Response) error {

   return func(resp *http.Response) error {

       b, err := ioutil.ReadAll(resp.Body)

       if err != nil {

           return err

       }


       err = resp.Body.Close()

       if err != nil {

           return err

       }


       b = bytes.Replace(b, []byte(orig), []byte(replace), -1)

       body := ioutil.NopCloser(bytes.NewReader(b))


       resp.Body = body

       resp.ContentLength = int64(len(b))

       resp.Header.Set("Content-Length", strconv.Itoa(len(b)))


       return nil

   }

}


func Frontend(w http.ResponseWriter, r *http.Request) {

   origin, _ := url.Parse("http://localhost:5000/")

   director := newDirector(*origin)

   proxy := &httputil.ReverseProxy{Director: director}

   proxy.ServeHTTP(w, r)

}


func liverload_js(w http.ResponseWriter, r *http.Request) {

   origin, _ := url.Parse("http://localhost:35729/")

   director := newDirector(*origin)

   modifier := newReplacer("this.port = 35729;", "this.port = 443;")

   proxy := &httputil.ReverseProxy{Director: director, ModifyResponse: modifier}

   proxy.ServeHTTP(w, r)

}



按下 F5 会重新加载,但热重新加载不会通过 ws 代理。


它如何包含在代理中?


RISEBY
浏览 134回答 2
2回答

杨__羊羊

自由职业者帮我找到了答案。诀窍是我在每个代理请求中都使用了 Scheme="http",甚至 httputil.ReverseProxy 本身也支持 websocket。func newDirector(origin url.URL) func(*http.Request) {   return func(req *http.Request) {       req.Header.Add("X-Forwarded-Host", req.Host)       req.Header.Add("X-Origin-Host", origin.Host)       req.URL.Scheme = "http"       req.URL.Host = origin.Host   }}应该func newDirector(origin url.URL) func(*http.Request) {   return func(req *http.Request) {       req.Header.Add("X-Forwarded-Host", req.Host)       req.Header.Add("X-Origin-Host", origin.Host)       req.URL.Scheme = origin.Scheme       req.URL.Host = origin.Host   }}完整的代码变成了package mainimport (    "bytes"    "io/ioutil"    "log"    "net/http"    "net/http/httputil"    "net/url"    "strconv")func newDirector(origin url.URL) func(*http.Request) {    return func(req *http.Request) {        req.Header.Add("X-Forwarded-Host", req.Host)        req.Header.Add("X-Origin-Host", origin.Host)        req.URL.Scheme = origin.Scheme        req.URL.Host = origin.Host    }}func newReplacer(orig, replace string) func(resp *http.Response) error {    return func(resp *http.Response) error {        b, err := ioutil.ReadAll(resp.Body)        if err != nil {            return err        }        err = resp.Body.Close()        if err != nil {            return err        }        b = bytes.Replace(b, []byte(orig), []byte(replace), -1)        body := ioutil.NopCloser(bytes.NewReader(b))        resp.Body = body        resp.ContentLength = int64(len(b))        resp.Header.Set("Content-Length", strconv.Itoa(len(b)))        return nil    }}func Frontend(w http.ResponseWriter, r *http.Request) {    origin, _ := url.Parse("http://localhost:5000/")    director := newDirector(*origin)    proxy := &httputil.ReverseProxy{Director: director}    proxy.ServeHTTP(w, r)}func liverload_js(w http.ResponseWriter, r *http.Request) {    origin, _ := url.Parse("http://localhost:35729/")    director := newDirector(*origin)    modifier := newReplacer("this.port = 35729;", "this.port = 443;")    proxy := &httputil.ReverseProxy{Director: director, ModifyResponse: modifier}    proxy.ServeHTTP(w, r)}func liverload_ws(w http.ResponseWriter, r *http.Request) {    origin, _ := url.Parse("http://localhost:35729/")    director := newDirector(*origin)    proxy := &httputil.ReverseProxy{Director: director}    proxy.ServeHTTP(w, r)}func Bundle_js(w http.ResponseWriter, r *http.Request) {    origin, _ := url.Parse("http://localhost:5000/")    director := newDirector(*origin)    modifier := newReplacer(":35729/livereload.js?snipver=1", ":443/livereload.js?snipver=1")    proxy := &httputil.ReverseProxy{Director: director, ModifyResponse: modifier}    proxy.ServeHTTP(w, r)}func main() {    http.HandleFunc("/build/bundle.js", Bundle_js)    http.HandleFunc("/livereload.js", liverload_js)    http.HandleFunc("/livereload", liverload_ws)    http.HandleFunc("/", Frontend)    log.Fatal(http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil))}

慕侠2389804

如果您安装 Caddy,那么您可以将其用作您的Caddyfile:http://localhost {    redir https://{host}{uri}}https://localhost {    tls /path/to/cert.crt /path/to/cert.key    proxy /API localhost:5000 {            without /API    }    proxy / localhost:5000}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go