Golang中HTTP服务出现panic:runtime error: invalid memory address or nil pointer dereference的解决方法

Golang中HTTP服务出现panic:runtime error: invalid memory address or nil pointer dereference的解决方法 大家好,我是Go语言的新手。我遇到了(标题中提到的)错误,以下是我的代码。请帮助我,我也附上了我的login.html文件。我不明白我的代码哪里出了问题。

package main
import (
	"fmt"
	"html/template"
	"log"
	"net/http"
	"strings"
)

func sayhelloName(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() //解析传递的URL参数,然后解析POST请求体(请求体)
	// 注意:如果不调用ParseForm方法,将无法获取到以下表单数据
	fmt.Println(r.Form) // 在服务器端打印信息
	fmt.Println("path", r.URL.Path)
	fmt.Println("scheme", r.URL.Scheme)
	fmt.Println(r.Form["url_long"])
	for k, v := range r.Form {
		fmt.Println("key:", k)
		fmt.Println("val:", strings.Join(v, ""))
	}
	fmt.Fprintf(w, "Hello astaxie!") // 将数据写入响应
}

func login(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method) //获取请求方法
	if r.Method == "GET" {
		t, _ := template.ParseFiles("login.html")
		t.Execute(w, nil)
	} else {
		r.ParseForm()
		// 登录逻辑部分
		fmt.Println("username:", r.Form["username"])
		fmt.Println("password:", r.Form["password"])
	}
}

func main() {
	http.HandleFunc("/", sayhelloName) // 设置路由规则
	http.HandleFunc("/login", login)
	err := http.ListenAndServe(":9090", nil) // 设置监听端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

这是我的HTML文件

<html>
<head>
    <title></title>
</head>
<body>
<form action="/login" method="post">
    Username:<input type="text" name="username">
    Password:<input type="password" name="password">
    <input type="submit" value="Login">
</form>
</body>
</html>

这是我遇到的错误。 当尝试访问 http://127.0.0.1:9090/login

method: GET
2020/01/02 17:31:25 http: panic serving 127.0.0.1:34910: runtime error: invalid memory address or nil pointer dereference
goroutine 62 [running]:
net/http.(*conn).serve.func1(0xc0000b1ea0)
        /snap/go/4901/src/net/http/server.go:1767 +0x139
panic(0x78de40, 0xae4fe0)
        /snap/go/4901/src/runtime/panic.go:679 +0x1b2
html/template.(*Template).escape(0x0, 0x0, 0x0)
        /snap/go/4901/src/html/template/template.go:95 +0x42
html/template.(*Template).Execute(0x0, 0x87b880, 0xc000130b60, 0x0, 0x0, 0x87b9c0, 0xc0001171a0)
        /snap/go/4901/src/html/template/template.go:119 +0x2f
main.login(0x881680, 0xc000130b60, 0xc000118b00)
        /home/mmt8037/go/src/awesomeProject1/main/goWeb.go:29 +0x357
net/http.HandlerFunc.ServeHTTP(0x815428, 0x881680, 0xc000130b60, 0xc000118b00)
        /snap/go/4901/src/net/http/server.go:2007 +0x44
net/http.(*ServeMux).ServeHTTP(0xaf4e40, 0x881680, 0xc000130b60, 0xc000118b00)
        /snap/go/4901/src/net/http/server.go:2387 +0x1bd
net/http.serverHandler.ServeHTTP(0xc0000ec000, 0x881680, 0xc000130b60, 0xc000118b00)
        /snap/go/4901/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc0000b1ea0, 0x881f40, 0xc00011aa00)
        /snap/go/4901/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
        /snap/go/4901/src/net/http/server.go:2928 +0x384
method: GET
2020/01/02 17:31:25 http: panic serving 127.0.0.1:34912: runtime error: invalid memory address or nil pointer dereference
goroutine 99 [running]:
net/http.(*conn).serve.func1(0xc0003680a0)
        /snap/go/4901/src/net/http/server.go:1767 +0x139
panic(0x78de40, 0xae4fe0)
        /snap/go/4901/src/runtime/panic.go:679 +0x1b2
html/template.(*Template).escape(0x0, 0x0, 0x0)
        /snap/go/4901/src/html/template/template.go:95 +0x42
html/template.(*Template).Execute(0x0, 0x87b880, 0xc0000ecc40, 0x0, 0x0, 0x87b9c0, 0xc00026c750)
        /snap/go/4901/src/html/template/template.go:119 +0x2f
main.login(0x881680, 0xc0000ecc40, 0xc000118c00)
        /home/mmt8037/go/src/awesomeProject1/main/goWeb.go:29 +0x357
net/http.HandlerFunc.ServeHTTP(0x815428, 0x881680, 0xc0000ecc40, 0xc000118c00)
        /snap/go/4901/src/net/http/server.go:2007 +0x44
net/http.(*ServeMux).ServeHTTP(0xaf4e40, 0x881680, 0xc0000ecc40, 0xc000118c00)
        /snap/go/4901/src/net/http/server.go:2387 +0x1bd
net/http.serverHandler.ServeHTTP(0xc0000ec000, 0x881680, 0xc0000ecc40, 0xc000118c00)
        /snap/go/4901/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc0003680a0, 0x881f40, 0xc00011aa80)
        /snap/go/4901/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
        /snap/go/4901/src/net/http/server.go:2928 +0x384
method: GET
2020/01/02 17:31:25 http: panic serving 127.0.0.1:34914: runtime error: invalid memory address or nil pointer dereference
goroutine 70 [running]:
net/http.(*conn).serve.func1(0xc000120820)
        /snap/go/4901/src/net/http/server.go:1767 +0x139
panic(0x78de40, 0xae4fe0)
        /snap/go/4901/src/runtime/panic.go:679 +0x1b2
html/template.(*Template).escape(0x0, 0x0, 0x0)
        /snap/go/4901/src/html/template/template.go:95 +0x42
html/template.(*Template).Execute(0x0, 0x87b880, 0xc0000ecd20, 0x0, 0x0, 0x87b9c0, 0xc00026c870)
        /snap/go/4901/src/html/template/template.go:119 +0x2f
main.login(0x881680, 0xc0000ecd20, 0xc000115000)
        /home/mmt8037/go/src/awesomeProject1/main/goWeb.go:29 +0x357
net/http.HandlerFunc.ServeHTTP(0x815428, 0x881680, 0xc0000ecd20, 0xc000115000)
        /snap/go/4901/src/net/http/server.go:2007 +0x44
net/http.(*ServeMux).ServeHTTP(0xaf4e40, 0x881680, 0xc0000ecd20, 0xc000115000)
        /snap/go/4901/src/net/http/server.go:2387 +0x1bd
net/http.serverHandler.ServeHTTP(0xc0000ec000, 0x881680, 0xc0000ecd20, 0xc000115000)
        /snap/go/4901/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc000120820, 0x881f40, 0xc0000b31c0)
        /snap/go/4901/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
        /snap/go/4901/src/net/http/server.go:2928 +0x384

请帮我找出代码中的问题。 提前感谢。


更多关于Golang中HTTP服务出现panic:runtime error: invalid memory address or nil pointer dereference的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

什么起作用了?

更多关于Golang中HTTP服务出现panic:runtime error: invalid memory address or nil pointer dereference的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


嘿 Skillian 谢谢。它起作用了。

在解析模板时,请检查返回的 error 值,而不是忽略它。可能是文件未找到或其他问题。

是的,谢谢。它起作用了。

我在解析文件时检查了错误,而不是忽略它。 结果发现它无法读取HTML文件,因为指定的路径不正确。 我将HTML文件移到了正确的路径,然后问题就解决了。

kmrsandeep98:

html/template.(*Template).Execute(0x0, 0x87b880, […]

Norbert 说得对。html/template.(*Template).Execute 的第一个参数(即模板对象本身)是 nil,所以很可能解析失败了并返回了一个 nil 模板。

你的代码问题在于template.ParseFiles("login.html")调用时没有正确处理错误。当模板文件无法加载时,t会变成nil,随后调用t.Execute(w, nil)就会导致空指针解引用。

错误堆栈显示:

html/template.(*Template).Execute(0x0, 0x87b880, 0xc000130b60, 0x0, 0x0, 0x87b9c0, 0xc0001171a0)

这里的0x0表示tnil指针。

修复方法:正确处理ParseFiles返回的错误:

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method)
    if r.Method == "GET" {
        t, err := template.ParseFiles("login.html")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        err = t.Execute(w, nil)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
        }
    } else {
        r.ParseForm()
        fmt.Println("username:", r.Form["username"])
        fmt.Println("password:", r.Form["password"])
    }
}

常见原因和解决方案:

  1. 文件路径问题:确保login.html文件位于程序运行的当前工作目录中。使用绝对路径或检查文件位置:
t, err := template.ParseFiles("/path/to/login.html")
// 或者
t, err := template.ParseFiles("./login.html")
  1. 文件权限问题:确保程序有读取模板文件的权限。

  2. 使用Must函数自动处理错误(更简洁的方式):

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method)
    if r.Method == "GET" {
        t := template.Must(template.ParseFiles("login.html"))
        t.Execute(w, nil)
    } else {
        r.ParseForm()
        fmt.Println("username:", r.Form["username"])
        fmt.Println("password:", r.Form["password"])
    }
}
  1. 预编译模板(推荐的生产环境做法):
var templates = template.Must(template.ParseFiles("login.html"))

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method)
    if r.Method == "GET" {
        templates.ExecuteTemplate(w, "login.html", nil)
    } else {
        r.ParseForm()
        fmt.Println("username:", r.Form["username"])
        fmt.Println("password:", r.Form["password"])
    }
}

检查你的login.html文件是否存在于程序运行的目录中。如果文件不存在或无法读取,ParseFiles会返回错误,而你的原始代码忽略了这些错误。

回到顶部