【问题标题】:Serve html directly from Google Cloud Storage and resolve relative links直接从 Google Cloud Storage 提供 html 并解析相关链接
【发布时间】:2021-01-10 10:50:37
【问题描述】:

我有一个简单的 html 文件,其中包含这样的 css:

<link rel="stylesheet" href="./css/style.css" />

我把这个html文件和css文件上传到google cloud storage,并设置权限为public。

在我的应用程序中,用 node js 编写,我想在用户访问我的根页面时提供这个 html 文件。

在我的应用程序中,我有以下代码:

public async getPublicFile(opts: IGetFileOpts): Promise<File> {
    const bucket = this.storage.bucket(opts.bucket);

    return bucket.file(path.join(opts.type, opts.fileName));
}

@Get()
public async serveFile(@Res() response: Response) {
    const file = await this.storageService.getPublicFile({
        organization: organization,
        fileName: 'index.html',
        type: 'resources',
    });

   file.createReadStream().pipe(response);
}

这按预期工作。它将从存储桶中服务index.html。但是,由于这个 html 文件有相对于 css 文件的链接,所以它不会加载 css 文件,因为它找不到它。

我该如何解决这个问题,以便也可以提供 css 文件?目前我在本地计算机上运行它,但它将部署到 Google Compute Engine。

我找到了这个 AppEngine 的链接https://cloud.google.com/appengine/docs/standard/go/serving-static-files

在 AppEngine 中,我可以像这样定义一些处理程序:

handlers:
  - url: /favicon\.ico
    static_files: favicon.ico
    upload: favicon\.ico

  - url: /static
    static_dir: public

  - url: /.*
    secure: always
    redirect_http_response_code: 301
    script: auto

但据我了解,这在本地机器上不起作用。

另外,电子商务公司如何解决这个问题?例如,每个商店都可以有不同的主题,可以定制。所以我知道每个租户都有自己的存储桶,并且在租户存储桶中,这个可自定义的主题保存正确吗?所以我如何假设应该像我一样有类似的问题。如何应对这种情况以及如何处理?

【问题讨论】:

  • 实际上,如果您更改为 Node.js 示例共享的文档链接,则有一整节内容是关于如何为本地开发提供文件,其中一个 .css 示例使用 express.static 来申请它,这里是特定部分的link,因此生产和本地开发都可以。当然,这是针对 AppEngine,而不是 Compute Engine,但它是一种可能的替代方案,这样就足够了吗?
  • 如果您的 css 目录可通过 http 或 https 访问,您可以在服务器端添加一个新的 &lt;base&gt; 标记,同时返回响应以更改页面的基本 URL。这样 html 由应用程序引擎提供服务,静态资产从云存储中提取。阅读更多关于base 标签here

标签: node.js google-cloud-platform google-cloud-storage e-commerce


【解决方案1】:

您目前正在尝试从 在您的 google 应用引擎 url 上提供的 index.html 访问存储桶静态 css 文件。这不能开箱即用。

有很多方法可以解决这个问题:

  • 从同一个存储桶中公开提供您的 index.html,您的其他静态文件(如 css)在哪里。这还具有将beeing用作更高效的CDN的好处。 (如果可能,这是我推荐的方式,唯一不能这样做的情况可能是当您想在将 index.html 文件发送回客户端之前计算服务器端 html 内容时,但很有可能可以做到这一点客户端)

  • “动态”或“静态”在 index.html 中构建指向您的 css 资源的绝对路径,因此链接标签可能如下所示:

<link rel="stylesheet" href="https://bucketurl.com/css/style.css" />
  • 使用特殊路由以编程方式为您的应用提供所有内容,该路由将通过从存储桶中读取文件来提供静态内容,就像使用 index.html 一样。这应该可以让您保留其他静态文件的相对路径。

【讨论】:

  • 能否请您详细说明第一点?因此,如果我想从数据库中提供一些东西,我需要提供 index.html,然后这个 index.html 应该调用后端 onPageLoad 或类似的东西。对吗?
  • 是的,就是这样,在这种情况下,您必须对某些 api(ajax 请求)进行一些前端 http 调用以与后端应用程序交互。执行此类查询可以返回您想要的任何数据,例如 json。在这种情况下,原始数据来自 API,而不是从后端生成并发送回客户端的 html 蜜蜂。您很快就会想要使用前端框架来处理常见的东西,例如来自 json 后端数据的水合模板。我会推荐 vue js,但反应,角度......会做的事情。这样做可能会导致您构建具有所有优点和缺点的 SPA(单页应用程序)。
  • 如果您朝这个方向发展,您可能还想坚持使用最少的前端代码并从后端加载 html 块。但是 2020 年很脏(2000 年还可以'^^)。它还很大程度上取决于您的“客户”目标是什么。你需要丰富的前端交互吗?一些原始的html表单就足够了吗?另请注意,深入研究前端应用程序是一个无穷无尽、令人兴奋和有益的话题(对我而言)。我回答你的问题了吗?
  • 是的,你做到了,我会接受你的回答,除了我对此评论有后续问题。我在我的问题中问电子商务平台如何解决这个问题?例如...我有多租户应用程序,每个租户都有不同的网页主题。如何根据租户服务不同的网页主题?此外,如果这在 2000 年还可以,而现在不行,您有什么建议可以在 2020 年做得更好吗? :)
  • 我不确定你的问题是否理解,但是,做多租户应用程序更复杂。这在很大程度上取决于您如何拆分租户。假设您每个子域都有一个租户:1)很难从静态存储桶中为它们提供全部服务,我认为您将希望通过在您的 cdn 前面放置一个反向代理来处理子域或类似的东西来处理这个问题,但是这超出了本主题的范围。您可能还更简单地拥有一个登录登录页面,当用户登录租户上下文时,会加载主题数据,并且会在 SPA 或服务器端页面呈现上相应地加载主题数据。
猜你喜欢
  • 1970-01-01
  • 2014-02-21
  • 2018-01-28
  • 2018-11-18
  • 1970-01-01
  • 2018-11-27
  • 1970-01-01
  • 2021-01-05
  • 2016-08-31
相关资源
最近更新 更多