英文:
More fluent cooperation of FileServe and Routing
问题
我有一个问题,我想在FileServe上为我的主要AngularJS(Yeoman部署)应用程序文件夹提供服务,路径为/
,但这将破坏我的所有路由绑定。有没有办法我可以保留它们并保持我的路由完整?
在下面的代码中,我仍然需要转到/app
并重新绑定其他文件夹,因为我不想过多地修改Grunt文件,所以为文件夹添加了一些额外的备份路径绑定。
func initializeRoutes() {
// 处理所有请求,通过提供相同名称的文件来提供服务
fileHandler := http.FileServer(http.Dir(*clFlagStaticDirectory))
bowerFileHandler := http.FileServer(http.Dir("../bower_components"))
imagesFileHandler := http.FileServer(http.Dir("../app/images"))
scriptsFileHandler := http.FileServer(http.Dir("../app/scripts"))
stylesFileHandler := http.FileServer(http.Dir("../app/styles"))
viewsFileHandler := http.FileServer(http.Dir("../app/views"))
// 设置路由
mainRoute := mux.NewRouter()
mainRoute.StrictSlash(true)
// mainRoute.Handle("/", http.RedirectHandler("/static/", 302))
mainRoute.PathPrefix("/app").Handler(http.StripPrefix("/app", fileHandler))
mainRoute.PathPrefix("/app/bower_components").Handler(http.StripPrefix("/bower_components", bowerFileHandler))
mainRoute.PathPrefix("/bower_components").Handler(http.StripPrefix("/bower_components", bowerFileHandler))
mainRoute.PathPrefix("/images").Handler(http.StripPrefix("/images", imagesFileHandler))
mainRoute.PathPrefix("/scripts").Handler(http.StripPrefix("/scripts", scriptsFileHandler))
mainRoute.PathPrefix("/styles").Handler(http.StripPrefix("/styles", stylesFileHandler))
mainRoute.PathPrefix("/views").Handler(http.StripPrefix("/views", viewsFileHandler))
// 基本路由
// 用户路由
userRoute := mainRoute.PathPrefix("/users").Subrouter()
userRoute.Handle("/login", handler(userDoLogin)).Methods("POST")
userRoute.Handle("/logout", handler(userDoLogout)).Methods("GET")
userRoute.Handle("/forgot_password", handler(forgotPassword)).Methods("POST")
// 绑定API路由
apiRoute := mainRoute.PathPrefix("/api").Subrouter()
apiProductModelRoute := apiRoute.PathPrefix("/productmodels").Subrouter()
apiProductModelRoute.Handle("/", handler(listProductModels)).Methods("GET")
apiProductModelRoute.Handle("/{id}", handler(getProductModel)).Methods("GET")
// 绑定通用路由
http.Handle("/", mainRoute)
}
所以我的目标是将/app
作为我的/
主路径进行服务,但保留所有的Mux路由以覆盖FileServe。所以如果我有一个/app/users/login
文件夹,它不会加载,而是让路由器生效。
注意:我纯粹通过HTTPS
提供服务,没有通过HTTP
。
非常感谢!这让我很困惑,这是我在开始我的前端代码之前需要解决的最后一件事情 :).
英文:
I have an issue where I want to serve my main AngularJS (Yeoman deployment) app folder on FileServe /
but it will destroy all my router bindings. Is there any way I can reserve them and keep my routes in-tact?
In the code below I still have to go to /app
and re-bind the other folders, because I don't want to temper with the Grunt file too much (yet), so added some extra backup path-bindings for the folders.
func initializeRoutes() {
// Handle all requests by serving a file of the same name
fileHandler := http.FileServer(http.Dir(*clFlagStaticDirectory))
bowerFileHandler := http.FileServer(http.Dir("../bower_components"))
imagesFileHandler := http.FileServer(http.Dir("../app/images"))
scriptsFileHandler := http.FileServer(http.Dir("../app/scripts"))
stylesFileHandler := http.FileServer(http.Dir("../app/styles"))
viewsFileHandler := http.FileServer(http.Dir("../app/views"))
// Setup routes
mainRoute := mux.NewRouter()
mainRoute.StrictSlash(true)
// mainRoute.Handle("/", http.RedirectHandler("/static/", 302))
mainRoute.PathPrefix("/app").Handler(http.StripPrefix("/app", fileHandler))
mainRoute.PathPrefix("/app/bower_components").Handler(http.StripPrefix("/bower_components", bowerFileHandler))
mainRoute.PathPrefix("/bower_components").Handler(http.StripPrefix("/bower_components", bowerFileHandler))
mainRoute.PathPrefix("/images").Handler(http.StripPrefix("/images", imagesFileHandler))
mainRoute.PathPrefix("/scripts").Handler(http.StripPrefix("/scripts", scriptsFileHandler))
mainRoute.PathPrefix("/styles").Handler(http.StripPrefix("/styles", stylesFileHandler))
mainRoute.PathPrefix("/views").Handler(http.StripPrefix("/views", viewsFileHandler))
// Basic routes
// User routes
userRoute := mainRoute.PathPrefix("/users").Subrouter()
userRoute.Handle("/login", handler(userDoLogin)).Methods("POST")
userRoute.Handle("/logout", handler(userDoLogout)).Methods("GET")
userRoute.Handle("/forgot_password", handler(forgotPassword)).Methods("POST")
// Bind API Routes
apiRoute := mainRoute.PathPrefix("/api").Subrouter()
apiProductModelRoute := apiRoute.PathPrefix("/productmodels").Subrouter()
apiProductModelRoute.Handle("/", handler(listProductModels)).Methods("GET")
apiProductModelRoute.Handle("/{id}", handler(getProductModel)).Methods("GET")
// Bind generic route
http.Handle("/", mainRoute)
}
So my goal is the serve /app
as my /
main path, but reserve all my Mux Routes to win over the FileServe. So if I'll have a /app/users/login
folder, it won't load, but instead it will let the Router win.
Note: I'm serving purely over HTTPS
and nothing over HTTP
.
Thanks so much in advance! This is breaking my brain and it's the last thing I need to figure out before I can fully start on my front-end code :).
答案1
得分: 1
看起来你想要改变路由的评估顺序,使得/users
、/login
等路径在/
之前匹配,而/
路径应该由FileServer处理。
据我所知,路由将按照它们被定义的顺序进行匹配(添加到路由器中)。所以你只需要将API和其他动态路由放在/
之前即可。
以下代码可以实现类似的功能:
/test
路径的匹配在文件服务器之前进行评估,并返回字符串"OK"- 然后文件服务器返回路径下的文件
代码:
package main
import (
"github.com/gorilla/mux"
"net/http"
)
func main() {
appFileHandler := http.FileServer(http.Dir("/Users/alex/Projects/tmp/so/app"))
r := mux.NewRouter()
r.PathPrefix("/test").HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("OK"))
})
r.PathPrefix("/").Handler(appFileHandler)
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
希望对你有帮助!
英文:
It looks for me like you want to change the order of how the routes are evaluated in a way that /users
, /login
, and similar are matched before the /
. And the /
should be server by the FileServer.
As far as I know, the routes will be matched in the order they are defined (added to the router). So you just have to move your API and other dynamic routes before /
.
The following code works similar:
- the
/test
match is evaluated before the file server and returns the string "OK" - then the file server returns the file under the path
Code:
package main
import (
"github.com/gorilla/mux"
"net/http"
)
func main() {
appFileHandler := http.FileServer(http.Dir("/Users/alex/Projects/tmp/so/app"))
r := mux.NewRouter()
r.PathPrefix("/test").HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("OK"))
})
r.PathPrefix("/").Handler(appFileHandler)
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论