You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"。


问题原因

  1. 根路由未注册:当前代码仅注册了/static/和/multiply两个路径的处理器,根路径/没有对应的处理逻辑,HTTP服务器找不到匹配路由时返回404。
  2. 模板路径错误:multiplyHandler中调用template.ParseFiles("index.html"),但实际index.html位于./static/目录下,路径不匹配会导致500错误(即使访问/multiply也无法正常工作)。
  3. 缺少用户输入界面:现有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:39:56