文件服务器对所有文件返回404错误。

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

Fileserver returns 404 for all files

问题

每当我尝试访问静态子目录中的任何文件时,都会收到404错误,而访问Home/则正常工作,但是我从home文件中调用的图片却无法显示。所以我想知道要更改什么,以便我既可以提供文件,又可以同时重定向我的根目录。

我的路径结构如下:

root/
->html
->static
->entry.go

我看到其他帖子上都建议我使用r.PathPrefix("/")。Handler(...),但是这样做会导致访问静态文件夹外的任何文件返回NIL,包括我的html文件,它们位于项目根目录的一个单独的html文件中,此外,重定向到其中任何一个都会返回404错误。

以下是代码:

package main

import (
  "fmt"
  "net/http"
  "html/template"
  "github.com/gorilla/mux"
  "os"
)

func IfError(err error, quit bool) {
  if err != nil {
    fmt.Println(err.Error())
    if(quit) {
      os.Exit(1);
    }
  }
}

func NotFound(w http.ResponseWriter, r *http.Request) {
  w.WriteHeader(404)
  t, _ := template.ParseFiles("html/404")
  err := t.Execute(w, nil)
  IfError(err, false)
}

func Home(w http.ResponseWriter, r *http.Request) {
  t, _ := template.ParseFiles("html/home")
  err := t.Execute(w, nil)
  IfError(err, false)
}

func RedirectRoot(servefile http.Handler) http.Handler {
  return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == "/" {
      redirect := r.URL.Host+"/home"
      http.Redirect(w, r, redirect, http.StatusSeeOther)
    } else {
      servefile.ServeHTTP(w, r)
    }
  })
}

func main()  {
  r := mux.NewRouter()
  ServeFiles := http.StripPrefix("/", http.FileServer(http.Dir("static/")))
  r.Handle("/", RedirectRoot(ServeFiles))
  r.HandleFunc("/home", Home)
  r.NotFoundHandler = http.HandlerFunc(NotFound)

  fmt.Printf("Listening ...")
  IfError(http.ListenAndServe(":8081", r), true)
}

非常感谢!

英文:

So whenever I try to access any files in my static sub-directory, I just get a 404, Not Found, Accessing Home/ on the other hand works just fine, but a picture that I call from the home file is simply broken :(, So I'd like to know what to change so that I can serve files and redirect my root directory at the same time.

My Path structure:

root/
->html
->static
->entry.go

I saw the other threads on here, they all recommend that I do r.PathPrefix("/").Handler(...), but doing that makes it so accessing any file outside static returns NIL, including my html files which are in a separate html file in the root of my project, furthermore, redirecting to any of them returns 404, Not Found.

Here's the code:

package main

import (
  "fmt"
  "net/http"
  "html/template"
  "github.com/gorilla/mux"
  "os"
)

func IfError(err error, quit bool) {
  if err != nil {
    fmt.Println(err.Error())
    if(quit) {
      os.Exit(1);
    }
  }
}

func NotFound(w http.ResponseWriter, r *http.Request) {
  w.WriteHeader(404)
  t, _ := template.ParseFiles("html/404")
  err := t.Execute(w, nil)
  IfError(err, false)
}

func Home(w http.ResponseWriter, r *http.Request) {
  t, _ := template.ParseFiles("html/home")
  err := t.Execute(w, nil)
  IfError(err, false)
}

func RedirectRoot(servefile http.Handler) http.Handler {
  return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == "/" {
      redirect := r.URL.Host+"/home"
      http.Redirect(w, r, redirect, http.StatusSeeOther)
    } else {
      servefile.ServeHTTP(w, r)
    }
  })
}

func main()  {
  r := mux.NewRouter()
  ServeFiles := http.StripPrefix("/", http.FileServer(http.Dir("static/")))
  r.Handle("/", RedirectRoot(ServeFiles))
  r.HandleFunc("/home", Home)
  r.NotFoundHandler = http.HandlerFunc(NotFound)

  fmt.Printf("Listening ...")
  IfError(http.ListenAndServe(":8081", r), true)
}

Thank you very much

答案1

得分: 0

我在你的代码中看到的问题是:

r.Handle("/", RedirectRoot(ServeFiles))

这个路由会匹配所有的路径,可能会产生意想不到的结果。相反,你应该清晰明确地映射你的路由,这样它才能按照你的期望工作。

例如:让我们根据你的目录结构来映射处理程序。这种方法只会通过文件服务器公开static目录,其他文件和根目录是安全的。

func main() {
   r := mux.NewRouter()
   r.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
   r.HandleFunc("/home", Home)
   r.NotFoundHandler = http.HandlerFunc(NotFound)
   
   fmt.Printf("Listening ...")
   IfError(http.ListenAndServe(":8081", r), true)
}

对于你的目的,可能不需要RedirectRoot

现在,/static/*http.FileServer提供,/homeHome处理。


编辑:

根据评论中的要求,将根路径/映射到Home处理程序,并添加以下内容来处理/favicon.ico

func favIcon(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "static/favicon.ico")
} 

r.HandleFunc("/favicon.ico", favIcon)
r.HandleFunc("/", Home)

favicon.icostatic目录中提供。

英文:

The issue I see in your code

r.Handle("/", RedirectRoot(ServeFiles))

It will match every route, may produce unexpected results. Instead map your routes clearly and explicitly then it will work as you expect.

For eg.: Let's maps the handler with responsibility. This approach based on your directory structure.

It will only expose static directory via file server, remaining files and root directory is safe.

func main()  {
   r := mux.NewRouter()
   r.Handle("/static/", http.StripPrefix("/static/",    http.FileServer(http.Dir("static"))))
   r.HandleFunc("/home", Home)
   r.NotFoundHandler = http.HandlerFunc(NotFound)
   
   fmt.Printf("Listening ...")
   IfError(http.ListenAndServe(":8081", r), true)
}

RedirectRoot may not be needed for your purpose.

Now, /static/* served by http.FileServer and /home handled by Home.


EDIT:

As asked in the comment. To map root / to home handler and /favicon.ico, add following in-addition to above code snippet.

func favIcon(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "static/favicon.ico")
} 

r.HandleFunc("/favicon.ico", favIcon)
r.HandleFunc("/", Home)

favicon.ico served from static directory.

huangapple
  • 本文由 发表于 2017年7月2日 09:59:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/44866837.html
匿名

发表评论

匿名网友

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

确定