You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web无法识别Dart后端CORS配置,求助解决方案

问题分析与解决方案

核心问题排查

  1. Origin不匹配:你设置的Access-Control-Allow-Origin为https://localhost,但Flutter Web默认运行在http://localhost:<端口>,协议或端口不匹配会直接触发CORS拦截。
  2. OPTIONS请求未动态适配:前端发送的OPTIONS预检请求会携带Access-Control-Request-Headers,固定返回允许头的方式无法匹配前端实际发送的自定义头,导致浏览器拒绝后续请求。
  3. 中间件顺序逻辑:当前CORS中间件在contentTypeJson之后执行,可能导致部分响应头覆盖或未正确合并。

修正后的CORS中间件实现

import 'package:shelf/shelf.dart';

class MiddlewareInterception {
  static Middleware get contentTypeJson => createMiddleware(
        responseHandler: (Response res) => res.change(
          headers: {
            'content-type': 'application/json',
            'xpto': '123',
          },
        ),
      );

  static Middleware get cors {
    return createMiddleware(
      requestHandler: (Request req) {
        // 处理OPTIONS预检请求
        if (req.method == 'OPTIONS') {
          // 动态获取前端请求的Origin
          final origin = req.headers['origin'] ?? '*';
          // 匹配前端发送的自定义请求头
          final requestHeaders = req.headers['access-control-request-headers'] ?? '';

          final corsHeaders = {
            'Access-Control-Allow-Origin': origin,
            'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
            'Access-Control-Allow-Headers': requestHeaders.isNotEmpty ? requestHeaders : 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
            'Access-Control-Allow-Credentials': 'true',
            'Access-Control-Max-Age': '86400',
          };

          return Response(200, headers: corsHeaders);
        }
        return null;
      },
      responseHandler: (Response res) {
        // 给所有业务响应添加CORS头
        final origin = res.request?.headers['origin'] ?? '*';
        return res.change(headers: {
          'Access-Control-Allow-Origin': origin,
          'Access-Control-Allow-Credentials': 'true',
        });
      },
    );
  }
}

调整中间件执行顺序

将CORS中间件移至contentTypeJson之前,确保所有请求先经过CORS校验:

final handler = Pipeline()
    .addMiddleware(logRequests())
    .addMiddleware(MiddlewareInterception.cors)
    .addMiddleware(MiddlewareInterception.contentTypeJson)
    .addHandler(cascadeHandler);

前端Flutter Web请求配置

若后端启用了Access-Control-Allow-Credentials: true,前端请求必须同步开启withCredentials:

import 'package:http/http.dart' as http;
import 'dart:convert';

final response = await http.post(
  Uri.parse('http://your-backend-ip:8080/api'),
  body: jsonEncode({'key': 'value'}),
  headers: {'Content-Type': 'application/json'},
  withCredentials: true, // 必须添加该参数
);

额外验证步骤

  • 打开浏览器开发者工具的网络面板,查看OPTIONS请求的响应头是否包含正确的Access-Control-Allow-Origin和允许的请求头。
  • 确认后端服务绑定的IP为0.0.0.0(而非127.0.0.1),确保前端能正常访问。

内容的提问来源于stack exchange,提问作者GTorraski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:57:24