【问题标题】:Static pages return 404 in Google App Engine静态页面在 Google App Engine 中返回 404
【发布时间】:2026-01-25 03:25:02
【问题描述】:

我一直在使用 Golang 测试 Google App Engine SDK,但在提供静态 html 页面时遇到了问题。如果我在处理程序下的app.yaml 中添加内容,那很好,但是当我尝试从我的 Go 应用程序内部路由它时;尝试 url http://localhost:8080/tr 页面返回 404。

我的文件系统设置为:

/main.go
/app.yaml
/testRoute.html

我的主要app.go 看起来像这样:

import (
    "fmt"
    "net/http"
    "github.com/gorilla/mux"
)

func init() {
    r := mux.NewRouter()
    r.HandleFunc("/", index)
    r.HandleFunc("/tr", testRoute)
    http.Handle("/", r)
}

func index(w http.ResponseWriter, r *http.Request) {
   //No Issues here 
   fmt.Fprint(w, "Main Index.")
}

func testRoute(w http.ResponseWriter, r *http.Request) { 
    http.FileServer(http.Dir("testRoute.html")).ServeHTTP(w, r)
}

【问题讨论】:

  • 当你得到 404 - 文件是否仍然与app.yaml 中的静态文件处理程序模式匹配?如果是这样 - 那么问题可能是默认情况下文件被认为是静态工件或应用程序可读文件。如果两者都需要,则需要在app.yaml 中显式设置application_readable 标志。
  • 我已经更新了 app.yaml 以包含一个应用程序可读的文件处理程序(放置在静态文件夹中);我可以直接从浏览器访问索引文件,但是当使用 /tr 路由时,我仍然得到 404。

标签: google-app-engine go


【解决方案1】:

您不应该使用 Go 处理程序来处理静态文件(除非您想合并其他逻辑,例如高级日志记录或计数)。

您可以在应用的配置文件app.yaml 中定义静态文件处理程序。这在官方文档中有详细说明:Static file handlers

静态文件是针对给定 URL 直接提供给用户的文件,例如图像、CSS 样式表或 JavaScript 源文件。静态文件处理程序描述应用程序目录中的哪些文件是静态文件,以及哪些 URL 为它们提供服务。

为了提高效率,App Engine 将静态文件与应用程序文件分开存储和提供。默认情况下,静态文件在应用程序的文件系统中不可用。这可以通过将application_readable 选项设置为true 来更改。

可以通过两种方式定义静态文件处理程序:作为映射到 URL 路径的静态文件的目录结构,或者作为将 URL 映射到特定文件的模式。

要使 AppEngine 自动提供静态文件,请将此条目添加到您的 app.yaml

- url: /tr
  static_files: testRoute.html
  upload: testRoute.html

要自动提供静态文件的整个目录(包括子文件夹,递归),请将此条目添加到app.yaml

- url: /assets
  static_dir: assets

【讨论】:

  • 谢谢 icza。这有很大帮助;使用 http.FileServer 重新加载 app.yaml url 路径之一的最佳做法是什么?
  • @hairyCode “重新加载”是什么意思?
  • 在 Go 应用程序中,我想更改到 app.yaml 处理程序中提到的其他静态位置
  • @hairyCode 我仍然不确定我是否理解您想要做什么。您想更改/修改静态文件的响应吗?你不能那样做。如果您想要更改(变化)某些内容,那么它不应该是静态文件,而应该完全由您的 Go 处理程序提供。
  • 很抱歉造成混乱;假设根据 Go 应用程序的功能,我想将用户指向静态 html 页面 1.html 或 2.html;我不想修改静态内容,只是将用户解析到该页面。
【解决方案2】:

我通过使用 ServeFile 方法解决了这个问题;这也适用于文件夹(例如“/assets/testRoute.html”)

func testRoute(w http.ResponseWriter, r *http.Request) { 
    http.ServeFile(w, r, "testRoute.html")
}

【讨论】:

    最近更新 更多