最近在尝试 flutter web, 会遇到一个问题, app 没问题, 然而同样的代码在 web 里就不好使了, 主要就是跨域的问题

搜了一下各种方案都是 nginx 的, 但是我抄过来发现不好使..

所以自己摸索一下解决方案

这个方案只适合于本地开发调试, 真实部署时只有两种方案

  1. 让服务器 api 允许跨域
  2. 部署到和服务器同一个域名,同一个端口下

另: 目前个人还是觉得 flutter web 不适合商用, 比较适合的场景是, 没有 android/ios 插件的项目中做远端展示使用,比如内部就不用分发 apk/ipa 了, 那两个东西打包太慢了, 这时候直接用 flutter web 就比较靠谱了

下载 Caddy

官网: https://caddyserver.com/ 找最新版本下载

因为这货是 GO 语言开发的, 所以只有单文件就可以部署了

我是 mac os, 我用的是 brew 安装的, brew install caddy

安装好了以后查看一下版本, 一定要是 2.0+ 版本的

$ caddy version
v2.0.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=

注意: 因为这东西 2.0 版本有大更改, 配置文件和 1.x 并不通用, 我这里使用的是 2.0 语法, 1.x 版本的不要对号入座

配置 Caddyfile

注意: 文件名一定要是 Caddyfile, 大小写不能错

:8088 {
    reverse_proxy /* http://xxxx:80 {
        header_up Host {http.reverse_proxy.upstream.hostport}
        header_down Access-Control-Allow-Headers *
        header_down Access-Control-Allow-Origin *
    }
}

我这里使用的是 8088 端口, 远端端口是 80

注意 reverse_proxy 后面的 /* 不能拉下

接着 header_up 是反代中替换请求头 Host, 有的服务器会检查这个 host.

header_down 就是在下发的响应内添加响应头, 我这里测试这两个都需要有, 不然会跨域, 不知道为啥网上都说只添加Access-Control-Allow-Origin就可以了

启动

把 caddy 配置到环境变量, 或者用完整路径启动它, Caddyfile 应该在当前运行目录下

$ ls
Caddyfile

$ ~/Downloads/caddy run --watch
using adjacent Caddyfile
2020/06/06 06:12:12.262 INFO    admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2020/06/06 14:12:12 [INFO][cache:0xc0006b2b90] Started certificate maintenance routine
2020/06/06 06:12:12.263 INFO    tls     cleaned up storage units
2020/06/06 06:12:12.264 INFO    autosaved config        {"file": "/Users/cai/Library/Application Support/Caddy/autosave.json"}
2020/06/06 06:12:12.264 INFO    serving initial configuration
2020/06/06 06:12:12.264 INFO    watcher watching config file for changes        {"config_file": "Caddyfile"}

如果没有异常退出就说明成功了, 接着把你的请求的 host 替换为 localhost:8088 就可以了