Skip to main content

Li Zheng flyskywhy@gmail.com

前端 CDN 网址跨域访问后端 nodejs 应用负载均衡网址的方法

肇因

本来如果能像 gitlab 自动部署 nodejs 应用到阿里云 Kubernetes 集群中 所描述的前后端访问同一个域名从而不存在跨域问题,那是最方便的,无奈实际测试发现通过 CDN 来访问其回源的负载均衡提供的后端 API 性能相比直接通过负载均衡来访问会差 6 倍,即使改成号称能够提供动态加速功能的 CDN 的升级产品 DCDN 全站加速 也基本改善不大,下表就是阿里云 性能测试PTS 所得的针对 nodejs 应用简单返回内存中数据的 API 的压力测试结果:

场景平均TPS(次/秒)平均RT(ms)起止时间
www-get-cfg-dcdn177.6161.91起:2018-09-28 09:44:53 止:2018-09-28 09:47:53
www-get-cfg-nocdn899.6611.02起:2018-09-28 09:21:28 止:2018-09-28 09:24:28
www-get-cfg-cdn149.2568.68起:2018-09-28 09:13:09 止:2018-09-28 09:16:09

另外,如果 nodejs 应用提供了文件下载服务,则当文件较大时,在使用阿里云 CDN 的情况下,就有非常大的概率下载失败,此种应用则只能让前后端使用不用域名使得后端不使用 CDN 。而为了不在跨域时出现比如 不要再问我跨域的问题了 提到的安全问题,前后端代码需要配合处理完善。

方法

后端跨域设置可以在后端的 nginx.conf 或 nodejs 应用代码中设置,实际试验发现, nginx.conf 的跨域方法经常出现有一些 API 请求没有跨域成功的问题,而 nodejs 应用代码的跨域方法则全部跨域成功。

后端代码修改

这里以 nodejs 的 koa 框架所用的 kcors 组件为例,后端添加如下代码:

var cors = require('kcors');

...

app.use(cors({
credentials: true,
origin: ctx => {
// 带有 www. 前缀的是可能被 CDN 加速的前端静态网页的托管服务器地址,
// 没有 www. 前缀的是不在 CDN 后面因而不会被 CDN 延时 6 倍左右的后端服务器地址

// 如果前端网址本身就不带有 www. 前缀来访问,这里也是兼容性的
// 兼容前后端网址相同比如都带有 www. 前缀的情况
if (ctx.header.origin.replace(/^https?:\/\//, '').replace(/^www\./, '').replace(/:[0-9]+$/, '') === ctx.header.host.replace(/^www\./, '').replace(/:[0-9]+$/, '')) {
return ctx.header.origin;
}
},
}));

后端域名解析

云解析DNS 中点击 yourcompany.com解析设置 ,在 添加记录 的对话框中, 记录类型 选择 A主机记录@记录值负载均衡 实例的 IP 地址,如此就将没有 www. 前缀的后端服务器地址 yourcompany.com 解析到直接负载均衡的 IP 地址。

前端代码修改

将前端代码中原有的 www.yourcompany.com 语句修改为 yourcompany.com ,或者是将原来的

apiAddress = '';

修改为

apiAddress = location.origin.replace(/://www./, '://');

前端代码部署到 OSS

将前端代码部署到 OSS 地址而非原先后端 ECS 中的某个目录,并在 对象存储 OSS基础设置 | 静态页面 设置 默认首页index.html

前端代码 CDN 加速

CDN域名管理添加域名加速域名 设为 www.yourcompany.com业务类型 设为 图片小文件源站信息 设为部署着前端代码的 OSS 地址。

前端域名解析

云解析DNS 中点击 yourcompany.com解析设置 ,在 添加记录 的对话框中, 记录类型 选择 CNAME主机记录www记录值 为 CDN 域名管理www.yourcompany.com 的 CNAME ,如此就将带有 www. 前缀的前端静态网页的托管服务器地址 www.yourcompany.com 解析到 CDN 地址。

简化

由于不再需要 nginx ,gitlab 自动部署 nodejs 应用到阿里云 Kubernetes 集群中 文中的一些配置文件可以被简化。

删除 nginx.conf

简化 Dockerfile

Dockerfile 中的 nginx 相关内容也不再需要了,可简化为:

FROM debian:stretch-slim

COPY nodeapp ./
CMD ./nodeapp

注,发现不需要显示 EXPOSE 1234 也能让 docker 容器开放后端服务 nodeapp 开启的 1234 端口,这样又可以让 docker 镜像少编译一个层了。

修改 yaml

deploy.yamlsvc.yaml 中的 8010 端口修改为后端服务 nodeapp 开启的 1234 端口。