Flutter Web调用303接口无法跳转至Stripe结账页求助
解决方案
问题排查
设置followRedirects=false后仍自动重定向,大概率是http包的高层封装掩盖了底层配置,或者请求初始化时的配置未正确生效。以下是几种可行的解决思路:
方案1:修正http包请求配置,严格校验重定向状态码
确保明确判断响应状态码为3xx后再提取Location头,避免提前触发自动重定向:
import 'package:http/http.dart' as http; import 'package:url_launcher/url_launcher.dart'; void redirectToStripeCheckout() async { final request = http.Request('POST', Uri.parse('myURL')) ..followRedirects = false ..maxRedirects = 0; final client = http.Client(); final response = await client.send(request); // 仅处理3xx重定向响应 if (response.statusCode >= 300 && response.statusCode < 400) { final location = response.headers['location']; if (location != null) { // 处理相对路径的Location(如果服务器返回相对地址) final redirectUri = Uri.parse(location).isAbsolute ? Uri.parse(location) : Uri.parse('https://your-server-domain.com$location'); if (!await launchUrl(redirectUri, mode: LaunchMode.externalApplication)) { throw '无法打开结账页:$redirectUri'; } } else { throw '重定向响应缺少Location头'; } } else { throw '请求未返回重定向,状态码:${response.statusCode}'; } }
方案2:改用dart:io原生HttpClient,直接控制重定向行为
http包基于dart:io封装,改用原生HttpClient能更精准控制重定向逻辑,避免高层封装的干扰:
import 'dart:io'; import 'package:url_launcher/url_launcher.dart'; void redirectToStripeCheckout() async { final client = HttpClient(); final request = await client.postUrl(Uri.parse('myURL')); // 强制关闭自动重定向 request.followRedirects = false; request.maxRedirects = 0; final response = await request.close(); if (response.statusCode == 303) { final location = response.headers.value(HttpHeaders.locationHeader); if (location != null) { final redirectUri = Uri.parse(location).isAbsolute ? Uri.parse(location) : Uri.parse('https://your-server-domain.com$location'); if (!await launchUrl(redirectUri, mode: LaunchMode.externalApplication)) { throw '无法打开结账页:$redirectUri'; } } else { throw '303响应缺少Location头'; } } else { throw '请求未返回303重定向,状态码:${response.statusCode}'; } client.close(); }
方案3:服务器端调整(可选)
如果有权限修改服务器接口,可直接返回Stripe结账页的URL字符串(而非303重定向),前端拿到后直接用url_launcher打开,彻底规避重定向处理问题:
// 服务器返回示例(JSON格式) { "checkout_url": "https://checkout.stripe.com/pay/cs_test_xxx" } // 前端处理代码 import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:url_launcher/url_launcher.dart'; void redirectToStripeCheckout() async { final response = await http.post(Uri.parse('myURL')); if (response.statusCode == 200) { final data = jsonDecode(response.body); final checkoutUrl = data['checkout_url']; if (checkoutUrl != null) { await launchUrl(Uri.parse(checkoutUrl), mode: LaunchMode.externalApplication); } } }
内容的提问来源于stack exchange,提问作者Deja
相关产品推荐
相关产品推荐

