Go简易Web应用访问出现404页面未找到问题排查与解决
问题分析与解决:Go Web应用根路径访问404错误
问题场景
我在Debian Stable Linux系统上开发了一款简易Web应用,功能是接收用户输入的两个数字并返回乘积。应用目录结构如下:
. ├── ./main ├── ./main.go └── ./static ├── ./static/favicon.ico ├── ./static/index.html └── ./static/style.css
现有代码
main.go
package main import ( "fmt" "html/template" "log" "net/http" "strconv" ) type ViewData struct { Product int } func multiplyHandler(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { http.Error(w, "Error parsing form", http.StatusBadRequest) return } num1, err := strconv.Atoi(r.Form.Get("num1")) if err != nil { http.Error(w, "Invalid input for num1", http.StatusBadRequest) return } num2, err := strconv.Atoi(r.Form.Get("num2")) if err != nil { http.Error(w, "Invalid input for num2", http.StatusBadRequest) return } product := num1 * num2 data := ViewData{ Product: product, } tmpl, err := template.ParseFiles("index.html") if err != nil { http.Error(w, "Error parsing template", http.StatusInternalServerError) return } err = tmpl.Execute(w, data) if err != nil { http.Error(w, "Error rendering template", http.StatusInternalServerError) return } } func main() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static")))) http.HandleFunc("/multiply", multiplyHandler) fmt.Println("Server listening on port 8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
index.html
<!DOCTYPE html> <html> <head> <title>Multiplication Result</title> <link rel="stylesheet" type="text/css" href="/static/style.css"> </head> <body> <h1>Multiplication Result</h1> <p>Product: {{.Product}}</p> </body> </html>
style.css
body { font-family: Arial, sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; } h1 { color: #333; } p { color: #666; font-size: 18px; margin-bottom: 10px; }
问题现象
main.go编译无警告/错误,运行后显示"Server listening on port 8080",但访问http://localhost:8080时返回"404 page not found"。
问题原因
- 根路由未注册:当前代码仅注册了
/static/和/multiply两个路径的处理器,根路径/没有对应的处理逻辑,HTTP服务器找不到匹配路由时返回404。 - 模板路径错误:
multiplyHandler中调用template.ParseFiles("index.html"),但实际index.html位于./static/目录下,路径不匹配会导致500错误(即使访问/multiply也无法正常工作)。 - 缺少用户输入界面:现有
index.html仅显示结果,没有提供输入数字的表单,用户无法提交数据到/multiply接口。
解决方案
1. 注册根路径处理器
在main函数中添加根路径的处理逻辑,返回带输入表单的页面:
func rootHandler(w http.ResponseWriter, r *http.Request) { // 初始状态不显示结果 data := ViewData{ HasResult: false, } tmpl, err := template.ParseFiles("./static/index.html") if err != nil { http.Error(w, "Error parsing template", http.StatusInternalServerError) return } err = tmpl.Execute(w, data) if err != nil { http.Error(w, "Error rendering template", http.StatusInternalServerError) return } } func main() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static")))) http.HandleFunc("/", rootHandler) // 新增根路径处理 http.HandleFunc("/multiply", multiplyHandler) fmt.Println("Server listening on port 8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
2. 修正模板路径与结果显示逻辑
- 给
ViewData添加HasResult字段,控制结果的显示:type ViewData struct { Product int HasResult bool // 标记是否显示计算结果 } - 修改
multiplyHandler中的模板路径为./static/index.html,并设置HasResult为true:data := ViewData{ Product: product, HasResult: true, } tmpl, err := template.ParseFiles("./static/index.html")
3. 更新index.html添加输入表单
修改index.html,添加数字输入表单,并通过模板条件判断显示结果:
<!DOCTYPE html> <html> <head> <title>Multiplication Calculator</title> <link rel="stylesheet" type="text/css" href="/static/style.css"> </head> <body> <h1>Multiplication Calculator</h1> <form action="/multiply" method="post"> <label for="num1">Number 1:</label> <input type="number" id="num1" name="num1" required><br><br> <label for="num2">Number 2:</label> <input type="number" id="num2" name="num2" required><br><br> <button type="submit">Calculate Product</button> </form> {{if .HasResult}} <h2>Result</h2> <p>Product: {{.Product}}</p> {{end}} </body> </html>
内容的提问来源于stack exchange,提问作者rnso
相关产品推荐
相关产品推荐

