英文:
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 (
"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))
}
Following is index.html file:
<!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>
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(以提供所需的参数num1
和num2
):
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 (
"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")
+ 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.Handle("/static/", http.FileServer(http.Dir(".")))
http.HandleFunc("/multiply", multiplyHandler)
fmt.Println("Server listening on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Then open this URL in the browser (to provide the required parameters num1
and num2
):
http://localhost:8080/multiply?num1=5&num2=10
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论