Gorilla/mux SPA 无法正确提供静态目录
Gorilla/mux SPA does not serve static directory correctly
我正在尝试制作一个 SPA 网络应用程序,并从 gorilla mux 包中获取了这个示例
https://github.com/gorilla/mux#serving-single-page-applications
但是在我像那里描述的那样对路径进行一些更改之前它没有用 https://github.com/gorilla/mux/issues/588
当我在浏览器中打开一些路径 http://localhost:8080/somepage 时,它提供 index.html 和相关文件(css 和 js)。但是,如果我输入带有另一个斜线的路径,例如 http://localhost:8080/somepage/smt 它也服务于 index.html 但 js 和 css 不起作用,并且他们的代码更改为index.html 中的代码。所以我的 js 或 css 文件与 index.html 中的代码完全相同。我不知道为什么会这样,也不知道包的示例是如何工作的。
这是我的代码
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path, err := filepath.Abs(r.URL.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
path = filepath.Join(h.staticPath, r.URL.Path)
_, err = os.Stat(path)
if os.IsNotExist(err) {
//this called if the path is like that http://localhost:8080/any or ...any/somesubpage
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
return
} else if err != nil {
fmt.Println("500")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
//this called if the path is just http://localhost:8080
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}
func main() {
router := mux.NewRouter()
//api handlers
spa := spaHandler{staticPath: "./", indexPath: "index.html"}
router.PathPrefix("/").Handler(spa)
srv := &http.Server{
Handler: router,
Addr: "127.0.0.1:8080",
}
log.Fatal(srv.ListenAndServe())
}
staticPath 是 ./,因为如果我的 index.html 在某个文件夹中,这绝对行不通。
我在 Ubuntu 中使用了这个示例,没有进行任何更改,并且效果很好。可能是因为文件路径的工作方式不同。但我需要 Windows.
或者也许还有其他方法可以在 go 中制作水疗中心?
如果请求的文件不存在,您的代码将 return index.html
;例如,如果请求是 http://address.com/foo/bar/xxx.html
(并且该路径中没有 xxx.html
),那么 index.html
文件将被 returned。问题是,如果 index.html
包含 <script src="test.js"></script>
(或 src=./test.js
),则脚本标记将导致浏览器请求 http://address.com/foo/bar/test.js
(因为路径是 relative 并且原始请求的路径是 /foo/bar/
),这不会 return 预期的文件(index.html
将被 returned,因为请求的文件不存在!)。
将您的 html 更改为使用 absolute 路径(例如 <script src="/test.js"></script>
)意味着将请求正确的 javascript(或其他文件类型),而不管原始文件是什么请求路径。
我正在尝试制作一个 SPA 网络应用程序,并从 gorilla mux 包中获取了这个示例 https://github.com/gorilla/mux#serving-single-page-applications 但是在我像那里描述的那样对路径进行一些更改之前它没有用 https://github.com/gorilla/mux/issues/588
当我在浏览器中打开一些路径 http://localhost:8080/somepage 时,它提供 index.html 和相关文件(css 和 js)。但是,如果我输入带有另一个斜线的路径,例如 http://localhost:8080/somepage/smt 它也服务于 index.html 但 js 和 css 不起作用,并且他们的代码更改为index.html 中的代码。所以我的 js 或 css 文件与 index.html 中的代码完全相同。我不知道为什么会这样,也不知道包的示例是如何工作的。
这是我的代码
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path, err := filepath.Abs(r.URL.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
path = filepath.Join(h.staticPath, r.URL.Path)
_, err = os.Stat(path)
if os.IsNotExist(err) {
//this called if the path is like that http://localhost:8080/any or ...any/somesubpage
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
return
} else if err != nil {
fmt.Println("500")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
//this called if the path is just http://localhost:8080
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}
func main() {
router := mux.NewRouter()
//api handlers
spa := spaHandler{staticPath: "./", indexPath: "index.html"}
router.PathPrefix("/").Handler(spa)
srv := &http.Server{
Handler: router,
Addr: "127.0.0.1:8080",
}
log.Fatal(srv.ListenAndServe())
}
staticPath 是 ./,因为如果我的 index.html 在某个文件夹中,这绝对行不通。
我在 Ubuntu 中使用了这个示例,没有进行任何更改,并且效果很好。可能是因为文件路径的工作方式不同。但我需要 Windows.
或者也许还有其他方法可以在 go 中制作水疗中心?
如果请求的文件不存在,您的代码将 return index.html
;例如,如果请求是 http://address.com/foo/bar/xxx.html
(并且该路径中没有 xxx.html
),那么 index.html
文件将被 returned。问题是,如果 index.html
包含 <script src="test.js"></script>
(或 src=./test.js
),则脚本标记将导致浏览器请求 http://address.com/foo/bar/test.js
(因为路径是 relative 并且原始请求的路径是 /foo/bar/
),这不会 return 预期的文件(index.html
将被 returned,因为请求的文件不存在!)。
将您的 html 更改为使用 absolute 路径(例如 <script src="/test.js"></script>
)意味着将请求正确的 javascript(或其他文件类型),而不管原始文件是什么请求路径。