Flutter Web构建后API通信遇CORS问题:如何用Shelf服务器内部通信
用Shelf服务器代理Flutter Web应用解决CORS问题
核心方案
将Flutter Web的静态资源托管在Shelf服务器上,同时让Shelf作为API请求的代理层。这样前端所有请求都指向同域名同端口的服务器,彻底规避CORS限制,无需额外开启新端口。
具体实现步骤
1. 构建Flutter Web静态文件
先把你的Flutter Web应用编译为静态资源:
flutter build web
编译完成后,静态文件会生成在项目根目录的build/web文件夹中。
2. 添加Shelf相关依赖
在用于编写Shelf服务器的Dart项目的pubspec.yaml中添加以下依赖:
dependencies: shelf: ^1.4.1 shelf_static: ^1.1.2 shelf_proxy: ^1.0.4
执行dart pub get完成依赖安装。
3. 编写Shelf服务器代码
创建main.dart文件,代码如下:
import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:shelf_static/shelf_static.dart'; import 'package:shelf_proxy/shelf_proxy.dart'; import 'package:shelf_router/shelf_router.dart'; void main() async { // 托管Flutter Web静态资源 final staticHandler = createStaticHandler( 'build/web', // 指向Flutter Web构建后的静态文件目录 defaultDocument: 'index.html', ); // 创建API代理,将前端的/api请求转发到目标REST API服务器 final apiProxy = proxyHandler('https://your-target-api-domain.com/'); // 路由分配:优先处理API请求,再处理静态资源 final router = Router() ..get('/api/<path|.*>', (Request request, String path) { // 移除请求路径中的/api前缀,转发给目标API return apiProxy(request.change(path: path)); }) ..all('/<path|.*>', staticHandler); // 添加日志中间件,便于调试 final handler = Pipeline() .addMiddleware(logRequests()) .addHandler(router); // 启动服务器,监听指定端口(示例为8080) final server = await shelf_io.serve(handler, '0.0.0.0', 8080); print('服务器已启动:http://${server.address.host}:${server.port}'); }
4. 关键细节说明
- 静态资源托管:
createStaticHandler负责加载Flutter Web的HTML、CSS、JS等文件,用户访问根路径时自动返回index.html。 - API代理逻辑:前端发送的
/api/xxx格式请求会被转发到目标API服务器(替换为你的实际API域名),比如前端请求/api/users会被转发到https://your-target-api-domain.com/users,全程同端口通信,无CORS问题。 - 路由优先级:必须先定义API路由,再定义静态资源路由,避免API请求被静态资源处理器拦截。
5. 启动服务器
执行以下命令启动Shelf服务器:
dart run main.dart
访问http://localhost:8080即可正常使用Flutter Web应用,所有API请求都会通过Shelf代理转发,不再触发CORS限制。
生产环境部署
将Flutter Web的build/web目录与Shelf服务器代码一同部署,可通过dart compile exe main.dart将服务器编译为可执行文件,直接在服务器上运行即可,所有流量均通过同一个端口处理。
内容的提问来源于stack exchange,提问作者lotus550
相关产品推荐
相关产品推荐

