Dart http包设置followRedirects=false仍自动重定向,如何解决?
问题:Flutter中设置followRedirects=false无效,请求仍自动跟随重定向
我尝试用Flutter和Dart实现一个小型HTTP封装类,希望手动处理重定向以避免CORS问题,于是设置了request.followRedirects = false,但发现该设置完全无效,客户端仍会自动跟随重定向。
复现代码及场景
Dart HTTP封装类
import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; class HttpWrapper { http.Client httpClient = http.Client(); Future<http.StreamedResponse> backendHttpRequest( String method, String endpoint) async { String backendUrlBase = const String.fromEnvironment("backend_url_base"); var uri = Uri.parse(backendUrlBase + endpoint); http.Request request = http.Request(method, uri); request.followRedirects = false; var response = await httpClient.send(request); if (response.isRedirect) { debugPrint("Redirecting..."); // handle redirect return response; } else { return response; } } }
Express示例服务器
const express = require('express'); const app = express(); var cors = require('cors') const logger = require('morgan'); const PORT = 3000; app.use(logger('dev')); app.use(cors()) // Without middleware app.get('/endpointwhichredirects', function (req, res) { console.log("Redirecting..."); res.redirect('/user'); }); app.get('/user', function (req, res) { res.send("This is the user-page"); }); app.listen(PORT, function (err) { if (err) console.log(err); console.log("Server listening on PORT", PORT); });
调用代码
HttpWrapper httpWp = HttpWrapper(); res = httpWp.backendHttpRequest('Get', '/endpointwhichredirects');
服务器日志输出
> GET /endpointwhichredirects 302 3.051 ms - 27 > GET /user 304 2.986 ms - -
代码中的debugPrint("Redirecting...")从未触发,断点只进入非重定向分支。
原因及解决办法
核心原因
默认的http.Client()在Flutter不同环境下(移动端/Web)的底层实现会忽略请求对象的followRedirects设置,自动处理重定向,导致你的配置不生效。
解决步骤
根据运行环境选择对应的自定义客户端,全局禁用自动跟随重定向:
1. 移动端/桌面端(使用IOClient)
import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:http/io_client.dart'; import 'dart:io'; class HttpWrapper { late http.Client httpClient; HttpWrapper() { // 创建自定义HttpClient并禁用自动跟随重定向 final ioClient = HttpClient() ..followRedirects = false; httpClient = IOClient(ioClient); } Future<http.StreamedResponse> backendHttpRequest( String method, String endpoint) async { String backendUrlBase = const String.fromEnvironment("backend_url_base"); var uri = Uri.parse(backendUrlBase + endpoint); http.Request request = http.Request(method, uri); var response = await httpClient.send(request); if (response.isRedirect) { debugPrint("Redirecting..."); // 在这里手动处理重定向逻辑,比如读取Location头发起新请求 return response; } else { return response; } } }
2. Web环境(使用BrowserClient)
import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:http/browser_client.dart'; class HttpWrapper { late http.Client httpClient; HttpWrapper() { // 创建BrowserClient并禁用自动跟随重定向 httpClient = BrowserClient()..followRedirects = false; } Future<http.StreamedResponse> backendHttpRequest( String method, String endpoint) async { String backendUrlBase = const String.fromEnvironment("backend_url_base"); var uri = Uri.parse(backendUrlBase + endpoint); http.Request request = http.Request(method, uri); var response = await httpClient.send(request); if (response.isRedirect) { debugPrint("Redirecting..."); // 手动处理重定向逻辑 return response; } else { return response; } } }
补充说明
- 修改后,客户端会直接返回302响应,
response.isRedirect会变为true,触发你的手动处理逻辑。 - 手动处理重定向时,记得读取响应头中的
Location字段,自行构造新请求,同时注意处理CORS相关配置。
内容的提问来源于stack exchange,提问作者di-math
相关产品推荐
相关产品推荐

