为什么在这个简单的网络应用程序中找不到文件?

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

Why file is not found in this simple web application

问题

我正在使用很好的Debian Stable Linux。我有一个简单的Web应用程序,它从用户那里获取两个数字,并返回这两个数字的乘积。我的目录结构如下所示:

.
├── ./main
├── ./main.go
└── ./static
    ├── ./static/favicon.ico
    ├── ./static/index.html
    └── ./static/style.css

以下是我的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;
}

Go源代码文件main.go可以成功构建,没有任何警告或错误消息。

然后,我使用命令./main运行它。以下是消息:

Server listening on port 8080

然后,我在Firefox浏览器中打开URL:http://localhost:8080。然而,网页只显示:

404 page not found

问题出在哪里,如何解决?

英文:

I am working on Debian Stable Linux which is working very well. I have following directory structure for a simple Web application that takes 2 numbers from the user and returns the product of these 2 numbers:

.
├── ./main
├── ./main.go
└── ./static
    ├── ./static/favicon.ico
    ├── ./static/index.html
    └── ./static/style.css

I have following Go code:

package main
import (
&quot;fmt&quot;
&quot;html/template&quot;
&quot;log&quot;
&quot;net/http&quot;
&quot;strconv&quot;
)
type ViewData struct {
Product int
}
func multiplyHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, &quot;Error parsing form&quot;, http.StatusBadRequest)
return
}
num1, err := strconv.Atoi(r.Form.Get(&quot;num1&quot;))
if err != nil {
http.Error(w, &quot;Invalid input for num1&quot;, http.StatusBadRequest)
return
}
num2, err := strconv.Atoi(r.Form.Get(&quot;num2&quot;))
if err != nil {
http.Error(w, &quot;Invalid input for num2&quot;, http.StatusBadRequest)
return
}
product := num1 * num2
data := ViewData{
Product: product,
}
tmpl, err := template.ParseFiles(&quot;index.html&quot;)
if err != nil {
http.Error(w, &quot;Error parsing template&quot;, http.StatusInternalServerError)
return
}
err = tmpl.Execute(w, data)
if err != nil {
http.Error(w, &quot;Error rendering template&quot;, http.StatusInternalServerError)
return
}
}
func main() {
http.Handle(&quot;/static/&quot;, http.StripPrefix(&quot;/static/&quot;, http.FileServer(http.Dir(&quot;./static&quot;))))
http.HandleFunc(&quot;/multiply&quot;, multiplyHandler)
fmt.Println(&quot;Server listening on port 8080&quot;)
log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
}

Following is index.html file:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Multiplication Result&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Multiplication Result&lt;/h1&gt;
&lt;p&gt;Product: {{.Product}}&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;

Following is style.css file:

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;
}

The go source code file main.go gets built without any warning or error messages.

I then run it with command: ./main. Following is the message:

Server listening on port 8080

I then open the Firefox browser and put in url: http://localhost:8080 . However, the web page only shows:

404 page not found

Where is the problem and how can it be solved?

答案1

得分: 1

以下是您的代码更改(第二个更改不是必需的,但它简化了代码):

(注意:更改以diff格式显示。但不幸的是,它在stackoverflow上没有语法高亮显示)

 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, "解析表单错误", http.StatusBadRequest)
        return
    }
    num1, err := strconv.Atoi(r.Form.Get("num1"))
    if err != nil {
        http.Error(w, "num1的输入无效", http.StatusBadRequest)
        return
    }
    num2, err := strconv.Atoi(r.Form.Get("num2"))
    if err != nil {
        http.Error(w, "num2的输入无效", http.StatusBadRequest)
        return
    }
    product := num1 * num2
    data := ViewData{
        Product: product,
    }
-   tmpl, err := template.ParseFiles("index.html")
+   tmpl, err := template.ParseFiles("static/index.html")
    if err != nil {
        http.Error(w, "解析模板错误", http.StatusInternalServerError)
        return
    }
    err = tmpl.Execute(w, data)
    if err != nil {
        http.Error(w, "渲染模板错误", http.StatusInternalServerError)
        return
    }
 }
 
 func main() {
-   http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
+   http.Handle("/static/", http.FileServer(http.Dir(".")))
    http.HandleFunc("/multiply", multiplyHandler)
    fmt.Println("服务器监听端口8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
 }

然后在浏览器中打开此URL(以提供所需的参数num1num2):

http://localhost:8080/multiply?num1=5&num2=10
英文:

Here are the changes to your code (the second change is not necessary, but it simplifies the code):

(Note: the changes are displayed in the diff format. But unfortunately, it's not syntax highlighted by stackoverflow)

 package main
 
 import (
    &quot;fmt&quot;
    &quot;html/template&quot;
    &quot;log&quot;
    &quot;net/http&quot;
    &quot;strconv&quot;
 )
 
 type ViewData struct {
    Product int
 }
 
 func multiplyHandler(w http.ResponseWriter, r *http.Request) {
    err := r.ParseForm()
    if err != nil {
        http.Error(w, &quot;Error parsing form&quot;, http.StatusBadRequest)
        return
    }
    num1, err := strconv.Atoi(r.Form.Get(&quot;num1&quot;))
    if err != nil {
        http.Error(w, &quot;Invalid input for num1&quot;, http.StatusBadRequest)
        return
    }
    num2, err := strconv.Atoi(r.Form.Get(&quot;num2&quot;))
    if err != nil {
        http.Error(w, &quot;Invalid input for num2&quot;, http.StatusBadRequest)
        return
    }
    product := num1 * num2
    data := ViewData{
        Product: product,
    }
-   tmpl, err := template.ParseFiles(&quot;index.html&quot;)
+   tmpl, err := template.ParseFiles(&quot;static/index.html&quot;)
    if err != nil {
        http.Error(w, &quot;Error parsing template&quot;, http.StatusInternalServerError)
        return
    }
    err = tmpl.Execute(w, data)
    if err != nil {
        http.Error(w, &quot;Error rendering template&quot;, http.StatusInternalServerError)
        return
    }
 }
 
 func main() {
-   http.Handle(&quot;/static/&quot;, http.StripPrefix(&quot;/static/&quot;, http.FileServer(http.Dir(&quot;./static&quot;))))
+   http.Handle(&quot;/static/&quot;, http.FileServer(http.Dir(&quot;.&quot;)))
    http.HandleFunc(&quot;/multiply&quot;, multiplyHandler)
    fmt.Println(&quot;Server listening on port 8080&quot;)
    log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
 }

Then open this URL in the browser (to provide the required parameters num1 and num2):

http://localhost:8080/multiply?num1=5&amp;num2=10

huangapple
  • 本文由 发表于 2023年6月11日 23:50:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451270.html
匿名

发表评论

匿名网友

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

确定