有几种廉价的方法可以托管使用静态网站生成器(如 Jekyll、Hugo 或 Pelican)生成的静态网站: 整个博客是使用 Jekyll 静态生成的。但是,我无法使用上面的任何选项,因为在这个博客的生命周期中,我更改了域名、更改了 URL 方案并重命名了帖子,我想保留所有旧网址 我一直在使用 Apache 和最近在单个虚拟机上使用 nginx 来托管这个博客,这两种软件的重定向功能都可以正常工作,但我已经准备好将它托管在一个新的和不同的地方 上一篇文章描述了我如何使用 Google App Engine 和 Python 将 URL 从旧域重定向到新域,但现在我需要一种方法来提供静态内容 **和** 重定向来自同一域的 URL。同样的域重定向要求就是为什么我不能简单地使用 Google App Engine 的“仅静态内容”功能(链接在上面的列表中)。但是,我可以结合使用 Google App Engine 和一个简单的 Golang 应用程序来提供静态内容 ** 和 ** 相同的域重定向 ## 为什么选择 Google App Engine? 在深入阅读本文的其余部分之前,您可能想知道为什么要在 Google App Engine 上托管博客?以下是我的理由: - 如果您的流量符合 App Engine 的 28 个实例小时免费层和每天 1 GB 的出口流量,则托管博客几乎是免费的 - 推送更新是用一个命令完成的 - 使用 Stackdriver 集成日志记录和监控 - 根据流量模式自动上下缩放 - 只需点击几下,网络日志就可以轻松地推送到 BigQuery 之类的东西,以进行长期存储和临时分析 - 托管 SSL 证书使用 LetâÃÃÃs Encrypt ##先决条件 这篇文章假设如下: - 您熟悉 Google Cloud Platform (GCP) 并已创建 GCP 项目 - 你已经安装了谷歌云 SDK - 你已经验证了 针对您的 Google 帐户的 gcloud 命令 创建 GCP 项目 如果您还没有创建 **GCP 项目遵循以下步骤: - 打开网络浏览器,创建或登录 Google 帐户 - 导航到 GCP 控制台 - 如果这是您的第一个 GCP 项目,系统将提示您创建一个 GCP 项目。每个 Google 帐户都会获得 300 美元的信用额度,可在 12 个月内用于 GCP。您需要输入信用卡才能创建 GCP 项目,但在 300 美元信用额度用完或 12 个月到期之前不会被收取费用 - 如果这是一个新的 GCP 项目,您需要通过导航到 GCP 控制台的计算引擎部分启用计算引擎 API,并等待初始化完成 安装谷歌云 SDK 如果您还没有安装 **谷歌云 SDK 按照此处的说明进行操作 验证 gcloud 创建 GCP 项目并安装 Google Cloud SDK 后,最后一步是验证 gcloud 命令到您的 Google 帐户。打开终端应用程序并运行以下命令: gcloud 授权登录 网页将在您的网络浏览器中打开。选择您的 Google 帐户并授予其访问 GCP 的权限。完成后,您将通过身份验证并准备好继续前进 ## 创建一个目录 接下来,在您工作站的某个位置创建一个目录来存储您的 Google App Engine 应用程序: mkdir ~/Sites/example.com/app_engine 更改到该目录: cd ~/Sites/example.com/app_engine 这篇文章的其余部分将假设您正在该目录中工作 另外,在里面创建一个目录 **app_engine** 目录名为 **static mkdir ~/Sites/example.com/app_engine/static 稍后您将重新访问此目录 ## 创建 app.yaml Google App Engine 通常需要两个文件: **app.yaml** 和一个用 Python、Golang、Java 或 PHP 编写的**应用程序文件**——在本例中,它将是 Golang。 **app.yaml** 提供运行应用程序所需的配置。 **app.yaml 中可以存在许多不同的参数,这些参数可能因使用的编程语言而异。对于这篇文章,将使用 Golang,您可以在此处找到所有可用的 Golang 参数 创建文件 **app.yaml** 包含以下内容: 运行时:转到 api_version:go1 处理程序:- url:脚本:_go_app 安全:始终 redirect_http_response_code:301 请注意 **安全:始终**已设置。这意味着 Golang 应用程序将始终通过 HTTPS 提供服务。如果最终用户通过 HTTP 导航到 Web 应用程序,他们将默认被 302 重定向到 HTTPS 版本。这就是为什么 **redirect_http_response_code: 301** 也被设置了。我一直希望 Web 应用程序通过 HTTPS 提供服务,我不希望搜索引擎将从 HTTP 到 HTTPS 的重定向解释为临时重定向;这是一个永久重定向 如果您有静态资产(您可能有),最好将此通知 App Engine 并让它从对象存储而不是您的应用程序中为这些资产提供服务。这样做很容易,也可以通过 **app.yaml** 文件 例如,如果您有一个图标文件、一个 CSS 目录、一个 Javascript 目录和一个图像目录,请使用以下命令 **app.yaml** 文件: 运行时:转到 api_version:go1 处理程序:- url:/favicon.png $ static_files:static/favicon.png 上传:static/favicon.png - url:/css static_dir:static/css - url:/js static_dir:static/js - url: /images static_dir: static/images - url:script: _go_app secure: always redirect_http_response_code: 301 ## 创建 main.go 接下来需要Golang应用文件 为以下代码满足您的需要,创建文件 **main.go 复制粘贴下面的代码,做如下修改: - 在里面 域变量,更改值以使用正确的 HTTP 协议匹配您的域名 - 在里面 urlsmap,替换所有键值对以匹配您需要的重定向。仅将每个键替换为当前域的路径部分(/example-post-1.html 而不是 httpsexample.com/example-post-1.html)- 您想要的旧 URL活着。然后将每个值替换为您要重定向到的当前域的新 URL 的路径部分 所有重定向都是 301 重定向。这可以通过更改来修改 下面代码中的 **301** 到不同的 HTTP 重定向状态代码,例如 **302** package main import ( "net/http""os""strings") func init() { http.HandleFunc handler) } func handler(w http.ResponseWriter, r *http.Request) { // True (ok) 如果请求path 在 urls map if value 中,ok := urls[r.URL.Path]; ok { value = domain + value http.Redirect(w, r, value, 301) } else { path := "static/"+ r.URL.Path // 如果 HTTP 请求是针对存在且确实存在的目录,则返回 403不包含 index.html 文件 if f, err := os.Stat(path); err == nil&& f.IsDir() { index := strings.TrimSuffix(path,+ "/index.html"if _, err := os.Open(index); err != nil { w.WriteHeader (403) w.Writebytehtml>