【问题标题】:Serve html file with custom status code使用自定义状态代码提供 html 文件
【发布时间】:2018-01-14 18:44:20
【问题描述】:

我需要一个自定义的未找到的 html 页面。这是我尝试过的:

package main

import (
    "net/http"

    "github.com/julienschmidt/httprouter"
)

func main() {
    r := httprouter.New()

    r.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(404)
        http.ServeFile(w, r, "files/not-found.html")
    })

    http.ListenAndServe(":8000", r)
}

我有w.WriteHeader(404)这一行来确保状态码是404,但是上面的代码给出了错误:

http:多个响应。WriteHeader 调用

没有w.WriteHeader(404)这行没有错误,页面显示正确,但是状态码是200,我希望是404。

【问题讨论】:

  • 一种方法是模拟 w,因此它不允许在传递给 http.servefile 时将状态代码更改为 200。

标签: go http-status-code-404


【解决方案1】:

大卫的回答奏效了,这是另一种方式。

// other header stuff
w.WriteHeader(http.StatusNotFound)
file, err := os.Open("files/not-found.html")
if err != nil {
    log.Println(err)
    return
}
_, err = io.Copy(w, file)
if err != nil {
    log.Println(err)
}
file.Close() // consider defer ^

【讨论】:

  • 延迟文件。关闭
【解决方案2】:

您可以简单地自己编写内容。

类似:

r.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        contents, err := ioutil.ReadFile("files/not-found.html")
        if err != nil {
            panic(err) // or do something useful
        }
        w.WriteHeader(404)
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
        w.Write(contents)
    })

【讨论】:

  • 我考虑过。使用 io.Copy 是否有更节省内存的方法?
  • 很可能,是的。你的 404 页面是否大到足以担心内存效率?
  • 如果 404 页面真的非常小,ioutil.ReadFile 的工作速度会比 io.Copy 快吗?
  • 如果您想要更快,我可能只是在开始时将内容加载到一个切片中,然后每次都编写它。没有理由每次都从磁盘加载,而且 404 页面可能不需要在服务器中“实时”更改。
猜你喜欢
  • 2012-11-10
  • 1970-01-01
  • 2014-08-01
  • 2018-05-06
  • 2010-12-06
  • 2012-11-19
  • 1970-01-01
  • 2019-10-25
  • 2012-11-20
相关资源
最近更新 更多