gpt4 book ai didi

戈朗。用什么? http.ServeFile(..) 还是 http.FileServer(..)?

转载 作者:IT老高 更新时间:2023-10-28 13:00:03 24 4
gpt4 key购买 nike

我有点困惑。许多示例显示了两者的用法:http.ServeFile(..)http.FileServer(..),但似乎它们具有非常接近的功能。我也没有找到有关如何设置自定义 NotFound 处理程序的信息。

// This works and strip "/static/" fragment from path
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))

// This works too, but "/static2/" fragment remains and need to be striped manually
http.HandleFunc("/static2/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, r.URL.Path[1:])
})

http.ListenAndServe(":8080", nil)

我尝试阅读源代码,它们都使用 serveFile(ResponseWriter, *Request, FileSystem, string, bool) 底层函数。然而 http.FileServer 返回 fileHandler 并带有自己的 ServeHTTP() 方法,并在提供文件之前做一些准备工作(例如 path.Clean()) .

那么为什么需要这种分离呢?哪种方法更好用?以及如何设置自定义 NotFound 处理程序,例如在未找到请求的文件时?

最佳答案

主要区别在于 http.FileServer 有效地将 HTTP 前缀与文件系统进行了几乎 1:1 的映射。用简单的英语,它提供了一个完整的目录路径。及其所有的 child 。

假设您有一个名为 /home/bob/static 的目录,并且您进行了以下设置:

fs := http.FileServer(http.Dir("/home/bob/static"))
http.Handle("/static/", http.StripPrefix("/static", fs))

您的服务器会接受请求,例如/static/foo/bar 并提供 /home/bob/static/foo/bar (或 404)中的任何内容

相比之下,ServeFile 是一个较低级别的帮助器,可用于实现类似于 FileServer 的东西,或者实现你自己的路径修改,以及任何数量的东西。它只是获取命名的本地文件并通过 HTTP 连接发送它。就其本身而言,它不会提供整个目录前缀(除非您编写了一个处理程序来进行类似于 FileServer 的一些查找)

注意天真地为文件系统提供服务是一件有潜在危险的事情(有潜在的方法可以打破根树)因此我建议除非你真的知道什么您正在这样做,使用 http.FileServerhttp.Dir 因为它们包含检查以确保人们无法突破 FS,其中 ServeFile 没有。

附录不幸的是,你的第二个问题,你如何做一个自定义的 NotFound 处理程序,不容易回答。因为正如您所注意到的,这是从内部函数 serveFile 调用的,所以没有 super 容易进入的地方。可能有一些偷偷摸摸的事情,比如用你自己的 ResponseWriter 拦截响应,它会拦截 404 响应代码,但我会把这个练习留给你。

关于戈朗。用什么? http.ServeFile(..) 还是 http.FileServer(..)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28793619/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com