此页面需要javascript支持,请在浏览器中启用javascript

在Serverless部署proxy助力前端开发

Serverless架构
前端开发
proxy
共1209个字,阅读时间 6 分钟
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://icebreaker.top/articles/2021/8/24-serverless-proxy

#! https://zhuanlan.zhihu.com/p/402874502 head image

在 Serverless 部署 proxy 助力前端开发

前言

我们前端开发人员,在开发中,经常会遇到跨域问题。

跨域问题实际上是浏览器自个加的限制,主要目的就是为了保障用户信息的安全,详见浏览器的同源策略

例如,前端页面在本地起在8080端口,起的后端部署在本地3000 端口,8080 发送 xhr 到 3000,结果就因为跨域策略挂了。

这时候我们通常会使用 2 种方式来帮我们解决:

  • 一种 服务端设置 CORS 策略来帮我们解决 (下文不涉及 jsonp )
    CORS 全称 Cross-Origin Resource Sharing,跨域资源共享
    它由众多的请求头组成,详见 MDN

  • 另一种 就是在开发时候,使用正向代理 (proxy) , 来帮助我们解决跨域问题。

这 2 种方式都是服务端的解决方案。

值得一提的是, Chrome 新的默认 Referrer-Policy : strict-origin-when-cross-origin , 在请求的 credentials modeinclude (XMLHttpRequest.withCredentials) 的情况下,Access-Control-Allow-Origin: * 默认是禁止的,必须显式声明

前端代理

刚刚也说过浏览器的同源策略,是自己给自己的一个限制,

所以我们可以在服务端自定义 http 请求,来绕过这一层限制,这就是使用正向代理的本质。

以前端最熟悉的 webpack-dev-server 配置为例:

// webpack.config.js
module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' }
      },
      '/baidu': {
        target: 'https://www.baidu.com',
        changeOrigin: true
      }
    }
  }
}

原理实际上非常简单,同源请求在 webpack-dev-serverhttp-proxy-middleware 中转化成服务端 http 请求,代理到目标域名那去罢了。

一图以蔽之:

webpack-dev-server proxy 原理

serverless 上构建 proxy

假如我们要把,本地的 webpack-dev-serverproxy 效果,直接部署到公网上,该怎么办呢?

最快的方式,就是,依靠 serverless framework , 直接把整个站 (包括前后端),部署到腾讯 SCF 平台,来作为我们线上网站的代理

主要有 2 种做法:

一种以使用 网站和 SCF 不同域名的方式来部署

另一种使用 网站和 SCF 相同域名的方式来部署

下面简称 多域名模式, 和 单域名模式

多域名模式

废话不多说,直接上图

多域名模式

这里我们把网站的静态资源,上传到 COS 上,再同步到 CDN

这样我们的网站实际部署在 CDN 上,给 CDN 配置域名之后,我们也只需要设置我们 SCF 绑定的 API网关cors 策略,把我们的域名加进去就可以。

这样用户从 CDN 获取页面和静态资源后,再向 SCF绑定的API网关域名发送跨站请求,以此达到代理的目的。

单域名模式

单域名模式就有些不同点了,还是看图

单域名模式

这里我们把网站的,除了作为入口的index.html, 其他的静态资源都上传到 COS 上,再同步到 CDN 那。

SCF 当然可以去返回静态资源,就是有点浪费算力。

这里我们把 index.html 放入了 SCF 内部,这样用户直接访问 API网关 的地址,就可以通过 static 中间件 + history fallback(router history mode) , 把页面返回给前端。

这里的 CDN 需要配置 CORS 策略,把 API网关 所绑定的自定义域名,设置进 CDN->高级配置 中的 HTTP响应头配置 规则里。

在图上可以看到,用户在访问 SCF 中的页面,以及向SCF发送请求的时候,都是走的同源的请求。

模式总结

可以看到,这 2 种模式都各有优劣,

  1. 对于我们部署静态网站或者资源来说,CDN 还是必不可少的,毕竟不同网络节点多,速度快,可以有效减少用户等待时间。
  2. 都需要配置 CORS 策略,只不过多域名模式,CORS 策略需要在 API 网关,或者SCF 内部代码中设置,单域名模式 , 其他静态资源的 CORS 策略 需要在CDN那里配置。

这篇文章最终写下来,实际上是探讨的在 Serverless 架构中,如何部署前端的方式。

假如我们使用的是服务端渲染 (SSR),可以看做成 单域名模式 的一种衍生,CDN作为动静分离的一种方式,内部动态的部分,还是放在SCF内部,交给它做渲染。

参考配置和实现代码

component: scf
name: sit-history-proxy

inputs:
  src:
    src: ./
    exclude:
      - .env
      - node_modules/**
      - yarn.lock
  type: web
  name: ${name}-function
  region: ap-shanghai
  runtime: Nodejs12.16
  installDependency: true
  entryFile: src/app.js
  eip: true
  environment:
    variables:
      NODE_ENV: production
  events:
    - apigw:
        parameters:
          protocols:
            - http
            - https
          environment: release
          endpoints:
            - path: /
              method: ANY

附代码