使用Angular.js进行Gorilla Mux路由。

huangapple go评论75阅读模式
英文:

Go with Gorilla Mux routing using Angular.js

问题

我似乎无法正确设置我的路由。我正在使用Gorilla Mux,并且我正在尝试从除了以"/foo"开头的任何URL之外的任何URL上提供我的Angular应用程序,基本上是我的index.html。

这个是有效的:

func StaticFileServer(w http.ResponseWriter, r *http.Request) {
  http.ServeFile(w, r, config.dir)
}

func main() {

  fs := http.Dir(config.dir)
  fileHandler := http.FileServer(fs)

  router = mux.NewRouter()

  router.Handle("/foo/page", PublicHandler(handler(getAll)).Methods("GET"))
  router.Handle("/foo/page/{id}", PublicHandler(handler(getOne)).Methods("GET"))

  router.PathPrefix("/{blaah}/{blaah}/").Handler(fileHandler)
  router.PathPrefix("/").HandlerFunc(StaticFileServer)

  ...
}

但肯定有比显式声明每个可能的路由更简单的方法,比如这个PathPrefix("/{blaah}/{blaah}/")的东西...
使用这个方法,除了/{blaah}/{blaah}/之外的任何其他URL都会返回404页面未找到,而不是index.html。

所以我想要的是,只要能找到,就将所有内容(静态文件等)提供出来,但其他所有内容都应返回/public/index.html。

英文:

I can't seem to get my routing right. I'm using Gorilla Mux and I'm trying to serve my angular app, so basically my index.html, from any url except them starting with "/foo".

This one works:

func StaticFileServer(w http.ResponseWriter, r *http.Request) {
  http.ServeFile(w, r, config.dir)
}

func main() {

  fs := http.Dir(config.dir)
  fileHandler := http.FileServer(fs)

  router = mux.NewRouter()

  router.Handle("/foo/page", PublicHandler(handler(getAll)).Methods("GET")
  router.Handle("/foo/page/{id}", PublicHandler(handler(getOne)).Methods("GET")

  router.PathPrefix("/{blaah}/{blaah}/").Handler(fileHandler)
  router.PathPrefix("/").HandlerFunc(StaticFileServer)

  ...
}

But there must be an easier way than to explicitly declaring every possible route, like this PathPrefix("/{blaah}/{blaah}/") thingy...
With this one, any other url than /{blaah}/{blaah}/ returns a 404 page not found, instead of index.html.

So I'd like to get everything served (static files etc.) as long as they can be found, but everything else should return /public/index.html.

答案1

得分: 1

我也遇到了同样的问题,但是如果我们使用Gorilla mux,我们可以清楚地解决这个问题。

因为Angular是一个单页应用程序,所以我们必须以这种方式处理。我有两个文件夹client和server。在client文件夹中,我保存了所有的Angular代码,在server文件夹中,我保存了所有的服务器代码,所以渲染index.html的静态路径是"client/dist"。这里的dist文件夹是一个Angular构建文件夹。

下面是Go路由器的代码:

func main() {
    router := mux.NewRouter()
    spa := spaHandler{staticPath: "client/dist", indexPath: "index.html"}
    router.PathPrefix("/").Handler(spa)
}

spaHandler实现了http.Handler接口,因此我们可以使用它来响应HTTP请求。静态目录的路径和静态目录中的索引文件的路径用于在给定的静态目录中提供SPA。

type spaHandler struct {
    staticPath string
    indexPath  string
}

ServeHTTP检查URL路径以在SPA处理程序的静态目录中定位文件。如果找到文件,它将被提供。如果没有找到文件,则将提供在SPA处理程序的索引路径上找到的文件。这适用于提供SPA(单页应用程序)的行为。

func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // 获取绝对路径以防止目录遍历
    path, err := filepath.Abs(r.URL.Path)
    if err != nil {
        // 如果无法获取绝对路径,则响应400错误请求并停止
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // 将路径与静态目录的路径连接起来
    path = filepath.Join(h.staticPath, path)

    // 检查给定路径是否存在文件
    _, err = os.Stat(path)
    if os.IsNotExist(err) {
        // 文件不存在,提供index.html
        http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
        return
    } else if err != nil {
        // 如果出现错误(不是文件不存在的错误),返回500内部服务器错误并停止
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 否则,使用http.FileServer来提供静态目录
    http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}

希望对你有帮助!

英文:

I was also facing the same issue but if we use Gorilla mux we have a clear solution for this.

Because Angular is a single page application so we have to handle that way. I have two folders client and server. Inside client folder I keep my all angular code and inside server folder I keep all server code so static path to render index.html is "client/dist". Here dist folder is a angular build folder.

Go router code is given below-

 func main {
        router := mux.NewRouter()
    	spa := spaHandler{staticPath: "client/dist", indexPath: "index.html"}
    	router.PathPrefix("/").Handler(spa)
}

spaHandler implements the http.Handler interface, so we can use it
to respond to HTTP requests. The path to the static directory and
path to the index file within that static directory are used to
serve the SPA in the given static directory.

type spaHandler struct {
	staticPath string
	indexPath  string
}

ServeHTTP inspects the URL path to locate a file within the static dir
on the SPA handler. If a file is found, it will be served. If not, the
file located at the index path on the SPA handler will be served. This
is suitable behavior for serving an SPA (single page application).

func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    // get the absolute path to prevent directory traversal
	path, err := filepath.Abs(r.URL.Path)
	if err != nil {
        // if we failed to get the absolute path respond with a 400 bad request
        // and stop
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

    // prepend the path with the path to the static directory
	path = filepath.Join(h.staticPath, path)

    // check whether a file exists at the given path
	_, err = os.Stat(path)
	if os.IsNotExist(err) {
		// file does not exist, serve index.html
		http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
		return
	} else if err != nil {
        // if we got an error (that wasn't that the file doesn't exist) stating the
        // file, return a 500 internal server error and stop
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
    
    // otherwise, use http.FileServer to serve the static dir
	http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}

答案2

得分: 0

我有点晚了,但其他人可能会发现我的答案有用。

基本上,Gorilla Mux 在这里处理你的所有路由。我假设你希望 AngularJS 对任何不以 "/foo" 开头的 URL 进行路由。

你可以使用正则表达式将任何不以 "/foo" 开头的请求发送到你的 index.html,代码如下:

router.PathPrefix("/{_:.*}").HandlerFunc(StaticFileServer)
英文:

I'm a bit late, but other people may find my answer useful.

Basically Gorilla Mux is doing all of your routings here. I'm assuming you want AngularJS to do the routing for any URL that doesn't start with "/foo".

You can use regex to send any requests that doesn't start with "/foo" to your index.html using:

router.PathPrefix("/{_:.*}").HandlerFunc(StaticFileServer)

huangapple
  • 本文由 发表于 2014年10月21日 18:02:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/26483975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定