Golang中net/http包调用非根路由时出现404错误的解决方法
Golang中net/http包调用非根路由时出现404错误的解决方法 我在 Stackoverflow 上发布了这个问题,但似乎没有人能够回答,所以我在此论坛重新发布。
如果有人能解答,我将非常感激,以下是问题的链接。
Stackoverflow 问题:
golang net/http give 404 error when trying to call other route that isn’t /
更多关于Golang中net/http包调用非根路由时出现404错误的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你的后端完全错了。你在同一路由上使用了两个文件服务器来提供页面。你应该为每个路由使用一个处理器,如下所示。
func handler(w http.ResponseWriter, r *http.Request) {
}
...
http.HandleFunc("/example", handler)
LE:基本上,一个文件服务器对你的应用来说就足够了。
更多关于Golang中net/http包调用非根路由时出现404错误的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
首先,你的404是文件未找到,而不是路由404。
状态1:你的文件错误。
如果 / 和 /example 是目录,你请求访问的文件是 ../frontend/public/index.html 和 ../frontend/public/exampme/index.html,请查看 net/http/fs.go 源代码。
/a.js -> ../frontend/public/a.js
[root@localhost tmp]# ls -R bruhurb/ frontend/
bruhurb/:
main.go
frontend/:
public
frontend/public:
example index.html
frontend/public/example:
index.html
[root@localhost tmp]# cat frontend/public/index.html
1
[root@localhost tmp]# cat frontend/public/example/index.html
2
[root@localhost tmp]# cd bruhurb/
[root@localhost bruhurb]# ls
main.go
[root@localhost bruhurb]# go run main.go
2020/04/08 22:42:53 Listening on http://locahost:8080
状态2:你的工作目录是临时目录或者工作目录错误。
添加代码 fmt.Println(os.Args[0]) 来显示工作目录。
如果使用 go run 命令启动服务器,Go 会使用一个临时目录运行,工作目录是临时的,否则相对路径是无效的,所以文件会返回404。
请使用 go build 并在工作目录中启动服务器,或者添加 os.Chdir 切换到工作目录。
这个问题通常是由于路由处理器注册不正确导致的。在net/http包中,默认的ServeMux对路由匹配有特定规则。以下是几种常见解决方案:
1. 使用HandleFunc注册精确路径
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home page")
})
http.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "API endpoint")
})
http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Data endpoint")
})
http.ListenAndServe(":8080", nil)
}
2. 使用自定义ServeMux并检查路径匹配
package main
import (
"fmt"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", homeHandler)
mux.HandleFunc("/api", apiHandler)
mux.HandleFunc("/api/data", apiDataHandler)
http.ListenAndServe(":8080", mux)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "Home page")
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "API endpoint")
}
func apiDataHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Data endpoint")
}
3. 使用第三方路由库(如gorilla/mux)
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", homeHandler)
r.HandleFunc("/api", apiHandler)
r.HandleFunc("/api/data", apiDataHandler)
http.ListenAndServe(":8080", r)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home page")
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "API endpoint")
}
func apiDataHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Data endpoint")
}
4. 检查中间件或处理器链的问题
package main
import (
"fmt"
"net/http"
)
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
next(w, r)
}
}
func main() {
http.HandleFunc("/", loggingMiddleware(homeHandler))
http.HandleFunc("/api", loggingMiddleware(apiHandler))
http.HandleFunc("/api/data", loggingMiddleware(apiDataHandler))
http.ListenAndServe(":8080", nil)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "Home page")
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "API endpoint")
}
func apiDataHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Data endpoint")
}
关键点:
- 确保路由处理器按正确顺序注册
- 根路径
/会匹配所有请求,需要在处理器中检查具体路径 - 使用
http.StripPrefix处理静态文件时可能影响路由 - 检查是否有其他中间件修改了请求路径
根据你的具体代码结构,选择适合的解决方案。如果问题仍然存在,请提供具体的代码片段以便进一步分析。

