在 Google Cloud Storage 中使用路由托管静态站点单页应用程序

问题描述 投票:0回答:5

到处都有关于如何做到这一点的指南和问题,但从来没有真正令人满意的具体答案。基本上,我想知道是否可以在 GCP Cloud Storage 中托管静态 SPA (HTML/CSS/JS)。

主要需要注意的是 SPA 有自己的路由系统 (ReactRouter),所以我希望所有路径都由 index.html 提供服务。

大多数指南会告诉您将 ErrorDocument 设置为

index.html
而不是
404.html
。虽然这是一个聪明的黑客,但它会导致网站的 HTTP 响应代码为 404,这对于 SEO 或监控工具来说是一场灾难。这样就可以了,只要我可以更改响应代码。

有什么办法可以做到这一点吗?我也启动并运行了 CloudFlare,但据我所知,无法从那里修剪路径或更改响应状态。

google-cloud-storage single-page-application cloudflare
5个回答
3
投票

这里的一个好方法是使用 Google App Engine 托管静态 SPA。 https://cloud.google.com/appengine/docs/standard/python/getting-started/hosting-a-static-website

您可以使用 app.yaml 文件将 url 映射到静态文件。这是一个例子:

runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /
  static_files: www/index.html
  upload: www/index.html

- url: /(.*)
  static_files: www/\1
  upload: www/(.*)

app.yaml 文档 https://cloud.google.com/appengine/docs/standard/python/config/appref


2
投票

规避该问题的一种方法是使用服务器端渲染。在 SSR 中,所有客户端请求都会传递到后端应用程序,因此不需要云存储托管

index.html

这当然有其自身的复杂性,但我们正在避免上述 404 黑客攻击或诉诸任何进一步的依赖项,例如 App Engine。

或者,您可以使用基于哈希的路由,即类似

https://example.com/#some-path
的路径。


2
投票

一个非常简单的解决方案是仅添加 index.html 文件作为 404 后备。这将始终将所有内容路由到您的单页应用程序。


0
投票

推荐的方法是在云存储桶前面放置一个全局外部负载均衡器。在负载均衡器中,您可以创建一个路由规则,它将每个请求重写到您的

index.html

defaultService: projects/xxxx/global/backendBuckets/spa
name: path-matcher-1
routeRules:
- matchRules:
  - pathTemplateMatch: /**
  priority: 10
  service: projects/xxxx/global/backendBuckets/spa
  routeAction:
    urlRewrite:
      pathTemplateRewrite: /index.html

-1
投票

如果您使用 Cloudflare,则可以使用 Cloudflare Worker 覆盖来自 Google Cloud Storage 错误页面的 404 状态代码。

Worker 的代码应该如下所示:

addEventListener('fetch', event => {
    event.respondWith(fetchAndLog(event.request))
})

async function fetchAndLog(req) {
    const res = await fetch(req)
    console.log('req', res.status, req.url)

    if (res.status === 404 && req.method === 'GET') {
        console.log('overwrite status', req.url)
        return new Response(res.body, {
            headers: res.headers,
            status: 200
        })
    }
    return res
}

我在 Cloudflare 社区这里找到了它。

© www.soinside.com 2019 - 2024. All rights reserved.