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

Flutter Web调用API重定向无法打开新页面,如何获取Location头?

获取后端重定向URL并打开新页面的解决方案

问题核心

你的场景中,http.post/http.head默认自动跟随重定向,导致无法拿到后端返回的初始重定向响应里的Location头;且直接设置followRedirects = false无效,是因为便捷方法(如http.post)会覆盖底层请求的配置,必须手动构建Request对象。


方法一:正确禁用自动重定向,提取Location头

手动构建Request并禁用重定向,直接获取后端的3xx响应,提取Location后打开新页面:

import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'package:universal_html/html.dart' as html;
import 'dart:convert';

// 发起请求
final request = http.Request('POST', Uri.parse('你的后端API地址'));
request.followRedirects = false;
request.headers['Content-Type'] = 'application/json';
// 添加请求体(根据你的需求调整)
request.body = jsonEncode({'username': 'xxx', 'password': 'xxx'});

final response = await http.Client().send(request);

// 处理重定向响应
if (response.statusCode >= 300 && response.statusCode < 400) {
  final location = response.headers['location'];
  if (location != null && kIsWeb) {
    html.window.open(location, 'Login');
  }
}

方法二:修改后端逻辑,直接返回重定向URL

如果禁用重定向仍有问题,可让后端不返回3xx重定向,而是返回200响应,将目标URL放在响应体或自定义头中:

后端Dart示例(以shelf框架为例):

import 'package:shelf/shelf.dart';
import 'dart:convert';

Response handleLoginRequest(Request req) {
  // 验证逻辑...
  final redirectUrl = 'https://外部网页地址';
  return Response.ok(
    jsonEncode({'redirectUrl': redirectUrl}),
    headers: {'Content-Type': 'application/json'},
  );
}

前端处理:

final response = await http.post(
  Uri.parse('你的后端API地址'),
  body: jsonEncode({'username': 'xxx', 'password': 'xxx'}),
  headers: {'Content-Type': 'application/json'},
);

final data = jsonDecode(response.body);
final redirectUrl = data['redirectUrl'];
if (redirectUrl != null && kIsWeb) {
  html.window.open(redirectUrl, 'Login');
}

关键注意点

  • 确保后端返回的Location或自定义字段是完整的外部URL(包含http/https前缀),避免相对路径导致打开失败
  • 使用kIsWeb判断环境,避免非Web平台调用html.window报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:53:15