当前位置: 首页 > 面试题库 >

使用go static文件服务器时,如何自定义处理找不到的文件?

闾丘鸣
2023-03-14
问题内容

因此,我正在使用Go服务器来提供单个页面的Web应用程序。

这适用于服务根路由上的所有资产。所有CSS和HTML均已正确提供。

fs := http.FileServer(http.Dir("build"))
http.Handle("/", fs)

因此,当URL为http://myserverurl/index.html或时http://myserverurl/styles.css,它将提供相应的文件。

但是对于类似的URL
http://myserverurl/myCustompage404如果myCustompage不是build文件夹中的文件,它将抛出。

如何使不存在文件的所有路由服务index.html

它是一个单页Web应用程序,一旦提供html和js,它将呈现适当的屏幕。但它需要index.html在没有文件的路由上提供。

如何才能做到这一点?


问题答案:

返回的处理程序http.FileServer()不支持自定义,它不支持提供自定义404页面或操作。

我们可以做的是包装由返回的处理程序http.FileServer(),并且在我们的处理程序中,我们当然可以做我们想做的任何事情。在包装器处理程序中,我们将调用文件服务器处理程序,如果该处理程序将发送404未找到的响应,则不会将其发送给客户端,而是将其替换为重定向响应。

为此,我们在包装器中创建了一个包装器http.ResponseWriter,该包装器将传递给由返回的处理程序http.FileServer(),在该包装器响应编写器中,我们可以检查状态代码,如果是404,我们可以采取行动
将响应发送给客户端,而是将重定向发送到/index.html

这是一个示例,该包装器http.ResponseWriter可能如下所示:

type NotFoundRedirectRespWr struct {
    http.ResponseWriter // We embed http.ResponseWriter
    status              int
}

func (w *NotFoundRedirectRespWr) WriteHeader(status int) {
    w.status = status // Store the status for our own use
    if status != http.StatusNotFound {
        w.ResponseWriter.WriteHeader(status)
    }
}

func (w *NotFoundRedirectRespWr) Write(p []byte) (int, error) {
    if w.status != http.StatusNotFound {
        return w.ResponseWriter.Write(p)
    }
    return len(p), nil // Lie that we successfully written it
}

并包装返回的处理程序http.FileServer()可能如下所示:

func wrapHandler(h http.Handler) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        nfrw := &NotFoundRedirectRespWr{ResponseWriter: w}
        h.ServeHTTP(nfrw, r)
        if nfrw.status == 404 {
            log.Printf("Redirecting %s to index.html.", r.RequestURI)
            http.Redirect(w, r, "/index.html", http.StatusFound)
        }
    }
}

请注意,我使用的是http.StatusFound重定向状态代码,而不是http.StatusMovedPermanently后者,因为后者可能被浏览器缓存,因此,如果稍后创建具有该名称的文件,浏览器将不会请求它,而是index.html立即显示。

现在使用该main()功能:

func main() {
    fs := wrapHandler(http.FileServer(http.Dir(".")))
    http.HandleFunc("/", fs)
    panic(http.ListenAndServe(":8080", nil))
}

尝试查询不存在的文件,我们将在日志中看到以下内容:

2017/11/14 14:10:21 Redirecting /a.txt3 to /index.html.
2017/11/14 14:10:21 Redirecting /favicon.ico to /index.html.

请注意,我们的自定义处理程序(行为良好)还将请求重定向到/favico.icoindex.html因为favico.ico我的文件系统中没有文件。如果您也没有,可以将其添加为例外。

完整的示例可在GoPlayground上找到。您无法在此处运行它,将其保存到本地Go工作区中并在本地运行。



 类似资料:
  • 我编写了一个自定义的NiFi处理器,用于在BigQuery上执行一些任务。我希望能够重用与NiFi捆绑在一起的GCP凭据提供者控制器服务,以用于身份验证。这可能吗?我尝试将nifi-gcp-processors maven依赖项添加到我的项目中,它成功构建,但当我尝试用我的nar启动NiFi时,它失败了,出现了这个错误消息。

  • 我第一次在项目中使用log4j,我试图为日志输出使用自定义配置。我希望记录器配置在自定义文件中,而不是log4j.xml或log4j.properties.这就是我现在所拥有的: 建造商: 第一次调用记录器的方法: (后面还有,但那不重要) test1.config的内容(即构造函数中loggerConfigFile的值) 我检查过了,配置文件在类路径中。 我希望这会导致记录器将一条语句写入控制台

  • 我已经使用下面的命令启动了selenium服务器,我想使用定制的firefox配置文件。但是,它如何为我运行的每个测试用例在/tmp/目录中创建一个新的firefoxprofile呢。 /usr/bin/java-jar/usr/local/groundwork/selenium/java/selenium-server-standalone-2.33.0。jar-firefoxProfileTe

  • 我使用struts jquery创建了一个页面,允许用户上传excel文件,并在不刷新页面的情况下显示内容。 当我尝试使用截取器将等待页面显示为远程页面时,我收到一个异常,告诉我它找不到文件的来源。 有人能提供一个答案吗? 更新我得到了空指针异常为上传的文件对象 java.lang.java.io.FileInputStream的空指针异常。)未知来源) 当我试图将一个文件对象(来自jsp页面)作

  • 用户,与猫一样,常常觉得有必要标记他们的领地。 与猫不同,用户往往要定制自己的 shell 环境,如终端显示的颜色、别名等。 这通常是通过用户家目录下的一些以点开始的环境文件实现的,例如:.bash_profile。 通过修改上一节的 user::virtual::ssh_user 类,你可以将环境文件添加到基于 Puppet 的用户管理中。 在这个类中,你可以有选择地为客户提供 Puppet 文

  • 问题内容: 我在Java项目中使用log4j。我想配置另一个文件,而不是log4j.properties。有人可以帮助我吗? 问题答案: 使用一次 您只需通过系统参数指定log4j文件的路径: