如何在 S3 上上传预渲染文件并在我们网页的初始加载时访问该文件?

Posted

技术标签:

【中文标题】如何在 S3 上上传预渲染文件并在我们网页的初始加载时访问该文件?【英文标题】:How to upload pre-rendered file on S3 and access that on initial load of our webpage? 【发布时间】:2017-05-29 16:15:22 【问题描述】:

我使用 Angular Universal Starter 工具包实现了我的 Web 应用程序。我想将预渲染文件上传到 S3 存储桶,以便我的初始页面加载更快。但是我找不到关于将预渲染文件上传到 S3 以及如何在初始加载时访问该文件的正确配置?

【问题讨论】:

我不确定您是指预编译模板渲染还是 html 页面渲染,但我相信 AngularJS 只是一个 javascript(客户端)框架,这意味着代码执行是在客户端执行的. EC2 实例不会呈现您的页面,浏览器会。您可以在此处阅读有关“在 Amazon S3 上托管静态网站”的更多信息:docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html 是的,我的意思是预编译的模板。我使用 webpack 来捆绑我的项目。所以现在很困惑如何将该预编译的包上传到 S3 并在初始加载时访问?我使用了 Angular Universal 入门工具包(服务器端渲染),因此服务器会生成一个包含渲染 HTML 的页面并返回到浏览器。 @Shailajashah 您能否详细说明您是如何预渲染您的 Angular 应用程序的? There is already question about it on SO 没有答案。非常感谢您的帮助! @Dmitry Angular Universal Kit 已经包含 webpack - 它用于捆绑我们所有的项目。所以我们可以使用 webpack 打包并上传这个包到 S3 上。 【参考方案1】:

使用预呈现的 HTML 与上传静态网站相同。假设您已安装并配置了 aws cli(使用 aws configure),您可以在目录上运行以下命令将文件上传到 s3 存储桶。

这只会上传/更新那些从 现有的存储桶文件。

aws s3 sync my_local_dir s3://my_s3_bucket_name

另外,如果你想设置缓存,那么你可以添加以下选项

aws s3 sync my_local_dir s3://my_s3_bucket_name --cache-control max-age=604800

【讨论】:

【参考方案2】:

Angular Universal 可用于动态 s-s-r(服务器端渲染)和静态预渲染

动态 s-s-r(服务器端渲染)无法通过 AWS S3 等静态文件托管来实现。它需要一个服务器端 Javascript 引擎 (nodejs) 来预渲染页面,然后再将其交给客户端浏览器; Amazon S3 除了提供一些静态文件之外没有任何功能。

另一方面,对于具有角度通用的静态预渲染,可以利用 AWS S3,因为它都是静态的 html/js/css 文件。但是有一个问题,每次静态文件内容更改时,您都必须启动构建/CI-CD 流程,以便将生成的静态文件部署到 S3 存储桶。如果这对您来说没问题,这与将任何其他静态站点部署到 S3 没有什么不同。

例如,

aws s3 sync ./dist/<your_awesome_ng_project> s3://<your_awesome_bucket_name>/ --delete.

您可以参考我正在构建一个角度项目并部署到 S3 存储桶https://github.com/jaisonpjohn/dbeaver-password-retriever-ng/blob/master/.circleci/config.yml 的此循环 CI 配置

更多关于动态 s-s-r(服务器端渲染)和静态预渲染

请参阅此article 以了解更多信息。我在这里引用相关部分

动态 s-s-r(服务器端渲染)和静态预渲染

动态 s-s-r 的概念是,将启动一个实时节点服务器,每当路由被命中时,它将动态生成和序列化应用程序——将该字符串返回给浏​​览器。

静态预渲染是当我们想要预渲染路由列表,并创建静态文件(即:index.html、about-us.html 等)然后使用我们选择的服务器稍后提供这些文件。

那么我们如何知道该选择哪一个以及何时选择?

预渲染通常会为您提供更好的性能,因为我们不需要等待服务器访问您应用程序中的所有必要 API,并且无需“序列化”任何内容,它已经拥有应用程序的所有序列化 HTML为每个 Routes 文件输出。

在决定走哪条路线之前,您需要考虑以下几点。

何时使用静态预渲染:

您的应用程序本身相当静态。 (或者至少是您尝试预渲染的路线) 例如:首页 |关于我们 |联系我们

您网站的非常动态的部分(以及登录/身份验证障碍后面的部分)可以指向您应用程序的正常客户端呈现 (CSR) 版本,并且 Angular 可以正常引导自身。

您的应用程序不会经常更新。 每当需要对静态路由进行一些更改时,您只需再次运行构建脚本并重新发布包含所有预渲染文件的 /dist 文件夹。

何时使用动态 s-s-r:

您的应用程序(以及 s-s-r 所需的路由)非常动态 您有一个“热门产品”列表 | “实时数据” |等等,您需要为每个服务器端渲染正确填充。 您的应用程序结构是基于 JSON 文件或 CMS 呈现的,任何东西都可能在任何给定时刻发生变化。

通常大多数应用程序都需要静态预渲染(因为身份验证墙后面的任何路由都不会从使用 s-s-r 中获得太多/任何好处,因为主要目的之一是 SEO 收益,并提高感知性能。 请记住,您始终可以让应用程序的某些方面在 s-s-r 期间不呈现,而在 CSR 期间填充这些动态部分!

一个类似的问题(这个问题是关于另一个静态文件服务器nginx,而不是S3):https://github.com/angular/universal/issues/554

顺便说一句,Angular Universal is part of the main ng project now

这个答案有点晚了,不知道你有没有得到答案。但我还是在这里添加它以帮助其他 SO 用户。

在这里开启赏金活动。

【讨论】:

【参考方案3】:

我已经在我当前的组织中实施了它。我的情况不同的是 由于库存,我们的内容是动态的。因此,我们过去只将预渲染页面发送给所有爬虫,而不是发送给真实用户。这样做的原因如下:

    不要将爬虫发送到真实服务器,否则会影响我们的分析。 为什么要为只需要静态数据的爬虫困扰我们的服务器。 最重要的是,大多数引擎无法呈现 Angular 标签。基本上它们不会在显示搜索结果之前在页面上执行 javascript。如果我们不这样做;我们网站的搜索结果看起来很糟糕。

我们是如何做到的:在我们的 nginx 上;如果用户代理是任何搜索引擎将请求传输到安装了https://github.com/prerender/prerender 的预渲染服务器(独立服务器),我们配置了规则。

最重要的是在这个预渲染服务器上配置了 s3HtmlCache 插件。这个插件首先检查页面是否在 S3 中可用;如果不是,它会在运行时创建页面 --> 保存在 s3 中 --> 发送到客户端。

所以,要解决您的问题:在您的 nginx 中;只需将所有请求传输到预渲染服务器。

如果您遇到任何问题,请告诉我。我已经实现了它,我知道这肯定会奏效。一切顺利。

【讨论】:

以上是关于如何在 S3 上上传预渲染文件并在我们网页的初始加载时访问该文件?的主要内容,如果未能解决你的问题,请参考以下文章

PUT 上传文件到 AWS S3 预签名 URL Retrofit2 Android

带有预签名 URL 和 CORS 问题的 S3 上传

使用预签名 URL 将文件上传到 Amazon S3 时出现 CORS 错误

如何使用 Python 在 myBucket 中上传 CSV 文件并在 S3 AWS 中读取文件

AWS S3 通过预签名 URL 上传返回 400 错误请求

如何对上传到 AWS S3 的文件执行自动病毒扫描