Golang创建表单实现文件读写操作时遇到错误怎么解决

Golang创建表单实现文件读写操作时遇到错误怎么解决 这是我的代码

package main

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
)

var tpl *template.Template

func inti() {
	tpl = template.Must(template.ParseGlob("templates/*"))
}

func main() {
	http.HandleFunc("/", foo)
	http.Handle("/favicon.ico", http.NotFoundHandler())
	http.ListenAndServe(":8080", nil)
}

// check error
func errorCheck(err error, w http.ResponseWriter) {
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

//foo call for route “/”
func foo(w http.ResponseWriter, req *http.Request) {
	var s string
	fmt.Println(req.Method)

	if req.Method == http.MethodPost {
		//open...
		f, h, err := req.FormFile("q")
		errorCheck(err, w)

		defer f.Close()

		fmt.Println("\nfile name: ", f, "\nheader:", h, "\nerror:", err)

		bs, err := ioutil.ReadAll(f)
		errorCheck(err, w)

		s = string(bs)

		//store on server...
		dst, err := os.Create(filepath.Join("./user/", h.Filename))
		errorCheck(err, w)

		defer dst.Close()

		_, err = dst.Write(bs)
		errorCheck(err, w)

	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	tpl.ExecuteTemplate(w, "index.gohtml", s)
}

这是我遇到的错误

2020/08/01 18:03:17 http: panic serving [::1]:36012: runtime error: invalid memory address or nil pointer dereference
goroutine 19 [running]:
net/http.(*conn).serve.func1(0xc0000c0fa0)
/usr/local/go/src/net/http/server.go:1772 +0x139
panic(0x780b80, 0xadc810)
/usr/local/go/src/runtime/panic.go:975 +0x3e3
html/template.(*Template).lookupAndEscapeTemplate(0x0, 0x7e6e17, 0xc, 0x0, 0x0, 0x0)
/usr/local/go/src/html/template/template.go:144 +0x4a
html/template.(*Template).ExecuteTemplate(0x0, 0x86bde0, 0xc0000fc0e0, 0x7e6e17, 0xc, 0x761160, 0xb18220, 0xc000047b78, 0x6ffdda)
/usr/local/go/src/html/template/template.go:133 +0x43
main.foo(0x871940, 0xc0000fc0e0, 0xc000118000)
/home/niteesh/Desktop/goworkspace/src/github.com/egnimos/golang_WEB_HTTP_package/passing_data/form_file_write/main.go:73 +0x23a
net/http.HandlerFunc.ServeHTTP(0x801810, 0x871940, 0xc0000fc0e0, 0xc000118000)
/usr/local/go/src/net/http/server.go:2012 +0x44
net/http.(*ServeMux).ServeHTTP(0xaec780, 0x871940, 0xc0000fc0e0, 0xc000118000)
/usr/local/go/src/net/http/server.go:2387 +0x1a5
net/http.serverHandler.ServeHTTP(0xc0000fc000, 0x871940, 0xc0000fc0e0, 0xc000118000)
/usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc0000c0fa0, 0x8722c0, 0xc0000c2300)
/usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2933 +0x35c
2020/08/01 18:03:17 http: panic serving [::1]:36014: runtime error: invalid memory address or nil pointer dereference
goroutine 20 [running]:
net/http.(*conn).serve.func1(0xc0000c1040)
/usr/local/go/src/net/http/server.go:1772 +0x139
panic(0x780b80, 0xadc810)
/usr/local/go/src/runtime/panic.go:975 +0x3e3
html/template.(*Template).lookupAndEscapeTemplate(0x0, 0x7e6e17, 0xc, 0x0, 0x0, 0x0)
/usr/local/go/src/html/template/template.go:144 +0x4a
html/template.(*Template).ExecuteTemplate(0x0, 0x86bde0, 0xc00019c000, 0x7e6e17, 0xc, 0x761160, 0xb18220, 0xc00004bb78, 0x6ffdda)
/usr/local/go/src/html/template/template.go:133 +0x43
main.foo(0x871940, 0xc00019c000, 0xc00006e000)
/home/niteesh/Desktop/goworkspace/src/github.com/egnimos/golang_WEB_HTTP_package/passing_data/form_file_write/main.go:73 +0x23a
net/http.HandlerFunc.ServeHTTP(0x801810, 0x871940, 0xc00019c000, 0xc00006e000)
/usr/local/go/src/net/http/server.go:2012 +0x44
net/http.(*ServeMux).ServeHTTP(0xaec780, 0x871940, 0xc00019c000, 0xc00006e000)
/usr/local/go/src/net/http/server.go:2387 +0x1a5
net/http.serverHandler.ServeHTTP(0xc0000fc000, 0x871940, 0xc00019c000, 0xc00006e000)
/usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc0000c1040, 0x8722c0, 0xc00005e040)
/usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2933 +0x35c
2020/08/01 18:03:17 http: panic serving [::1]:36016: runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
net/http.(*conn).serve.func1(0xc000072000)
/usr/local/go/src/net/http/server.go:1772 +0x139
panic(0x780b80, 0xadc810)
/usr/local/go/src/runtime/panic.go:975 +0x3e3
html/template.(*Template).lookupAndEscapeTemplate(0x0, 0x7e6e17, 0xc, 0x0, 0x0, 0x0)
/usr/local/go/src/html/template/template.go:144 +0x4a
html/template.(*Template).ExecuteTemplate(0x0, 0x86bde0, 0xc00007c000, 0x7e6e17, 0xc, 0x761160, 0xb18220, 0xc00004cb78, 0x6ffdda)
/usr/local/go/src/html/template/template.go:133 +0x43
main.foo(0x871940, 0xc00007c000, 0xc00006e100)
/home/niteesh/Desktop/goworkspace/src/github.com/egnimos/golang_WEB_HTTP_package/passing_data/form_file_write/main.go:73 +0x23a
net/http.HandlerFunc.ServeHTTP(0x801810, 0x871940, 0xc00007c000, 0xc00006e100)
/usr/local/go/src/net/http/server.go:2012 +0x44
net/http.(*ServeMux).ServeHTTP(0xaec780, 0x871940, 0xc00007c000, 0xc00006e100)
/usr/local/go/src/net/http/server.go:2387 +0x1a5
net/http.serverHandler.ServeHTTP(0xc0000fc000, 0x871940, 0xc00007c000, 0xc00006e100)
/usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc000072000, 0x8722c0, 0xc00005e100)
/usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2933 +0x35c

更多关于Golang创建表单实现文件读写操作时遇到错误怎么解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

是的,它确实存在

更多关于Golang创建表单实现文件读写操作时遇到错误怎么解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,这段代码启动了一个服务器。你具体执行了哪个请求导致了错误?

你确定 index.gohtml 文件存在吗?

非常感谢你的帮助……问题已经解决了。

确切的请求是什么?抱歉,但您能澄清一下您所说的内容吗?

这段代码启动了一个服务器,监听 localhost:8080 上的 HTTP 请求。您具体是向 http://localhost:8080/ 执行了哪个 HTTP 请求,从而导致了错误?

好的,所以你的意思是,在重定向到这个

http://localhost:8080/ URL

*时,重定向到这个 URL 时,

foo 函数被执行了


func main() {
    fmt.Println("hello world")
}

这是该函数的代码…

func foo(w http.ResponseWriter, req *http.Request) {
	var s string
	fmt.Println(req.Method)

	if req.Method == http.MethodPost {
		//打开...
		f, h, err := req.FormFile("q")
		errorCheck(err, w)

		defer f.Close()

		fmt.Println("\n文件名: ", f, "\n头部信息:", h, "\n错误:", err)

		bs, err := ioutil.ReadAll(f)
		errorCheck(err, w)

		s = string(bs)

		//存储在服务器上...
		dst, err := os.Create(filepath.Join("./user/", h.Filename))
		errorCheck(err, w)

		defer dst.Close()

		_, err = dst.Write(bs)
		errorCheck(err, w)

	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	tpl.ExecuteTemplate(w, "index.gohtml", s)
}

你的代码中存在两个主要问题:

  1. 模板初始化函数名拼写错误inti() 应该是 init()
  2. 模板执行时未检查错误tpl.ExecuteTemplate() 可能返回错误

以下是修复后的代码:

package main

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
)

var tpl *template.Template

func init() {
	tpl = template.Must(template.ParseGlob("templates/*"))
}

func main() {
	http.HandleFunc("/", foo)
	http.Handle("/favicon.ico", http.NotFoundHandler())
	http.ListenAndServe(":8080", nil)
}

// check error
func errorCheck(err error, w http.ResponseWriter) {
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

//foo call for route “/”
func foo(w http.ResponseWriter, req *http.Request) {
	var s string
	fmt.Println(req.Method)

	if req.Method == http.MethodPost {
		//open...
		f, h, err := req.FormFile("q")
		errorCheck(err, w)

		defer f.Close()

		fmt.Println("\nfile name: ", f, "\nheader:", h, "\nerror:", err)

		bs, err := ioutil.ReadAll(f)
		errorCheck(err, w)

		s = string(bs)

		//store on server...
		dst, err := os.Create(filepath.Join("./user/", h.Filename))
		errorCheck(err, w)

		defer dst.Close()

		_, err = dst.Write(bs)
		errorCheck(err, w)

	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	err := tpl.ExecuteTemplate(w, "index.gohtml", s)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

关键修改:

  1. inti() 改为 init() - Go会自动调用这个初始化函数
  2. tpl.ExecuteTemplate() 后添加错误检查

另外,确保你的项目目录结构正确:

project/
├── main.go
└── templates/
    └── index.gohtml

index.gohtml 模板文件示例:

<!DOCTYPE html>
<html>
<head>
    <title>File Upload</title>
</head>
<body>
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="q">
        <input type="submit" value="Upload">
    </form>
    {{if .}}
    <h3>File Content:</h3>
    <pre>{{.}}</pre>
    {{end}}
</body>
</html>

还需要确保 user/ 目录存在,或者在创建文件前检查目录:

// 在创建文件前添加目录检查
err = os.MkdirAll("./user/", 0755)
errorCheck(err, w)

dst, err := os.Create(filepath.Join("./user/", h.Filename))
errorCheck(err, w)
回到顶部