cloudflare page 教程(二)路由配置
在之前的文章中,谈到了如何初始化 cloudflare Pages。这篇文章将更输入的展开,讲解如何使用 pages 中的路由功能,和如何在实际中进行应用。
1. 跳转路由
Pages 提供了静态路由跳转的功能,方便你将一些旧有的页面路由迁移到新版本上去。注意这种路由是静态配置,不经过 Workers 代码动态处理,在 cloudflare 上是完全免费的,所以对于静态文件的跳转规则优先使用跳转路由。其实现方式也很简单,在项目构建目录中放置一个 _redirects
文件即可。
1.1 跨域名跳转
笔者之前是使用 github Pages 功能的,默认所有的开启 github Pages 的项目都挂载到一个域名上,但是 cloudflare Pages 支持每个项目单独设置域名。我将 yunnysunny/yunnysunny.github.io yunnysunny/nodebook 两个项目都迁移到了 cloudflare Pages,迁移后前者域名为 blog.whyun.com,后者域名为 node.whyun.com ;迁移前我将 yunnysunny.github.io 前面配置了 CDN 进行反代,CDN 的域名同样为 blog.whyun.com,所以迁移前两者对应的 github Pages 的访问地址分别为 https://blog.whyun.com 和 https://blog.whyun.com/nodebook 。迁移后,这里我们需要一个跳转规则保证在访问域名 blog.whyun.com 的 nodebook 路径时能够正常跳转到域名 node.whyun.com,为了实现上述目的我们在 _redirects
中写入如下一行配置即可:
代码 1.1.1
上述代码中我们使用了 301 跳转,是由于 /nodebook 路径在 blog.whyun.com 已经不再使用了,我们使用 301 是为了让新增的域名 node.whyun.com SEO 更友好。
我们将_redirects
放置在项目根目录了,但是如果想让其生效你需要在构建的时候,将其拷贝到构建输出目录中,除非你的构建输出目录就是你的项目根目录。
1.2 项目中跳转
假定你有一个静态页项目,里面的目录结构如下:
目录结构 1.2.1
我们程序的源代码在 browser.js 中编写,在 test 文件见下有一个测试网页 index.html ,为了方便双击 index.html 就能测试,我们在其内部通过<script src="../browser.js" type="text/javascript"></script>
来引入 browser.js 。现在我们想将这个项目部署到 cloudflare Pages 上去,想达到部署完之后输入域名就能打开这个 index.html 的目的,那么肯定需要将 test 文件夹设置为 Pages 的构建路径。但是这个 test 文件夹中没有 browser.js ,这个好办构建命令中将其拷贝到 test 文件夹即可。即使拷贝完成了,也有一个问题需要解决,index.html 中是通过 ../browser.js 引入的 js 文件,可现在它跟 index.html 在同一个目录了,这么写肯定是找不到文件的。解决这个问题的好方法还是使用 _redirects
文件做个声明:
代码 1.2.1
配置了上述代码之后,../browser.js 请求发送到 Pages 服务之后,其会自动去读取 /browser.js 路径映射的资源文件,这样就能完美的解决我们的问题。
我们之所以没有使用 1.1 小节的解决方案,是由于它会触发浏览器跳转,效率上不如当前直接代理请求。
上述配置的示例项目代码参见 yunnysunny/whyun-player 。
2. 动态路由
前面讲的是静态文件的路由,Pages 作为一个全栈解决方案,可以通过编写 Functions 代码来实现后端请求,我们学习 Node 后端框架(比如 Express、Koa )等,首先要学的就是路由怎么写,可见路由在任何框架中都是关键技术。
Functions 作为后起之秀,借鉴了一些其他框架的先进思想,它的路由设计和常见的 Next.js 有些类似,通过文件所在的相对路径来映射到 HTTP 的请求 Path 上。
我们现在假定,你想实现 /v1/user/add
/v1/user/remove
/v1/user/modify
三个路由,那么你可以在 functions 文件夹中放置如下文件:
目录结构 2.1
如果你嫌上述目录太分散了,不适合编写通用逻辑,那么你可以直接在 v1
文件夹下放置 [user].js
文件,做如下目录结构:
目录结构 2.2
对于 目录结构 2.1 我们在每个 js 文件中,直接编写业务逻辑即可
代码 2.1 add.js
但是对于目录结构 2.2 来说,你需要手动判断当前请求路径,在逻辑代码中再做一层路由:
代码 2.2 [user].js
你也可以将 [user].js
改名为 [[user]].js
,前者只能涵盖 /v1/user/xxx
这种路由,但是如果你有一个 /v1/user/internal/xxx
的路由,就必须得用 [[user]].js
,它能够涵盖所有以 /v1/user/
开头的路由。假设你想写一个反向代理服务,使用 [[]]
这种格式是比较方便的。下面是一段代理请求到 dockerhub 的代码:
代码 2.3 [[api]].js
上述文件 [[api]].js
放置到 functions/v2
目录下,然后将你的项目部署到 Pages 上,即可快速实现一个 dockerhub 镜像站的功能。
上述完整项目代码参见 whyun-pages/docker-registry (github.com) 。
3. 已知问题
3.1 动静态路由相互冲突问题
如果项目中的动态路由和静态路由之间有重合,那么 Pages 将默认使用动态路由。举一个例子,
目录 3.1.1
上述目录树中
public
为 Pages 的构建输出目录。
上述目录结构会导致所有请求都会由 [[proxy]].js
文件进行处理,这样我们在 public 目录中放置的 index.html 就白费了。想要网站输入域名后就能打开 index.html,我们可以在 public 目录中添加一个 _routes.json
文件:
代码 3.1.1 public/_routes.json
使用上述代码后,/
目录就可以正常加载 index.html
了。
3.2 输入不存在的路由时加载了 index.html 的内容
Pages 默认工作在单页应用模式,认为所有的请求路径在找不到时,都应该兜底返回 index.html 的内容。如果你想在请求路径不存在时返回 404,你需要在构建输出目录中放置一个 404.html 网页。
同样举一个例子,
目录结构 3.2.1
对于上述目录结构来说请求 /oauth2/callback
是存在的 ,请求 /
也是存在的,但是如过不做任何设置请求 /xxx
也会返回 index.html
的内容。现在我们在 public
目录下放一个 404.html
,请求 /xxx
就可以正常渲染 404
页面了。