dongpu42006096 2017-07-02 01:59
浏览 39
已采纳

文件服务器为所有文件返回404

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条回答 默认 最新

  • douyan2680 2017-07-02 02:56
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 iOS开发关于快捷指令截屏后如何将截屏(或从截屏中提取出的文本)回传给本应用并打开指定页面
  • ¥15 unity连接Sqlserver
  • ¥15 图中这种约束条件lingo该怎么表示出来
  • ¥15 VSCode里的Prettier如何实现等式赋值后的对齐效果?
  • ¥15 流式socket文件传输答疑
  • ¥20 keepalive配置业务服务双机单活的方法。业务服务一定是要双机单活的方式
  • ¥50 关于多次提交POST数据后,无法获取到POST数据参数的问题
  • ¥15 win10,这种情况怎么办
  • ¥15 如何在配置使用Prettier的VSCode中通过Better Align插件来对齐等式?(相关搜索:格式化)
  • ¥100 在连接内网VPN时,如何同时保持互联网连接