需要实现中间代理进行重定向,并且将加载出来后的html修改base中的href,使得可以成功加载其他需要的js、css…等文件。
先放源码:
func main() {
go func() {
s := new(server)
http.Handle("/dev/", &server{})
http.Handle("/dev", &server{})
http.Handle("/", &server{})
fmt.Println("start")
http.ListenAndServe(":8081", s)
}()
time.Sleep(time.Hour * 200000)
}
type server struct {
}
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
bol := r.RequestURI == "/index.html"
if strings.HasPrefix(r.RequestURI, "/dev") || bol {
newReq := new(http.Request)
*newReq = *r
newReq.RequestURI = ``
newReq.URL.Host = "127.0.0.1:8888"//真实的server的端口
newReq.URL.Scheme = "http"
newReq.URL.Path = strings.TrimPrefix(r.URL.Path, "/dev")
newReq.Header = r.Header
matchChar, _ := regexp.Match(`^(/dev/?)||(/index.html/?)$`, []byte(r.RequestURI))
if matchChar {
resp, err := http.DefaultClient.Do(newReq)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
bb, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
text := string(bb)
replacestr := `<base id="base_url" href="/dev/">`
reg := regexp.MustCompile(`<base id="base_url" href="/">`)
str := reg.ReplaceAllString(text, replacestr)
b1 := []byte(str)
for k, v := range resp.Header {
fmt.Println(k, v[0])
if k != "Content-Length" {
for i := 0; i < len(v); i++ {
w.Header().Add(k, v[i])
}
}
}
w.Write(b1)
} else {
resp, err := http.DefaultClient.Do(newReq)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
defer resp.Body.Close()
io.Copy(w, resp.Body)
b, _ := ioutil.ReadAll(resp.Body)
for k, v := range resp.Header {
fmt.Println(k, v[0])
if k != "Content-Length" {
for i := 0; i < len(v); i++ {
w.Header().Add(k, v[i])
}
}
}
w.Write(b)
}
}
}
1、
这里是匹配路由,如果URI的前缀是/dev,就重定向路由,改host、path。
2、
这里进行匹配,如果URI是/dev、/、/index.html,这三个,是跳转首页的,需要更改默认路由base。使用正则表达式将html中的内容进行替换,之前尝试过写一段js,然后读文件。但是逻辑有问题,js是后加载的,所以base等于没更改。
然后返回Body中内容。同时也要返回header中的信息。我用for range 将resp中的header 添加进responsewriter中。这边运行的时候报了一个错,是说 content-length 长度不符合,想了想是的,我把URI给改了长度肯定不一样,那怎么办呢?我去看了header源码。
翻了一段英文,简单来说,如果没有设置Content-Length ,header会给你自动添加。哦?那我就不要那个字段就好了呀。把字段和”Content-Length“不匹配的,全添加。
然后就可以了,开心。