Flutter使用Dio/Http发起Get请求遇401 Unauthorized问题求助
以下是针对该问题的排查方向和解决方案:
1. 清理Token冗余字符
SharedPreferences存储的Token可能夹杂空格、换行符等无效字符,导致实际发送的Token与Postman中不一致。读取时添加trim()处理,同时打印Token确认:
final bearerToken = SharedPreferencesManager.getString(LocalStorageConstants.userToken)?.trim(); debugPrint('当前使用的Token: $bearerToken'); // 与Postman中的Token完全对比
2. 补充缺失的请求头
Postman默认会自动携带部分请求头,Flutter代码中可能遗漏。尝试添加Content-Type头:
final headers = { 'Authorization': 'Bearer $bearerToken', 'Accept': 'application/json', 'Content-Type': 'application/json', };
3. 解决重定向导致的Token丢失
Http包默认自动跟随重定向,但重定向请求不会携带Authorization头,导致后续请求无Token返回401。禁用自动重定向并手动处理:
final response = await http.get( Uri.parse('http://ikseer.onrender.com/orders/cart/'), headers: headers, followRedirects: false, );
如果返回3xx状态码,提取响应头中的location字段,手动携带原请求头发起新请求。
4. 抓包对比请求细节
用Charles或Fiddler抓取Flutter请求和Postman请求,重点对比:
- 请求URL是否完全一致(包括末尾斜杠、参数等)
- Authorization头的内容是否完全匹配
- 所有请求头参数是否一致
修改后的示例代码
import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:graduation_project/core/localStorage/shared_preferences_storage.dart'; import '../../../core/constants/shared_pref_constants.dart'; class ItemsCartCall { static Future<List<dynamic>> getCartItems() async { // 读取Token并去除首尾冗余字符 final bearerToken = SharedPreferencesManager.getString(LocalStorageConstants.userToken)?.trim(); if (bearerToken == null || bearerToken.isEmpty) { throw Exception('Bearer token is missing or invalid'); } debugPrint('当前使用的Token: $bearerToken'); final headers = { 'Authorization': 'Bearer $bearerToken', 'Accept': 'application/json', 'Content-Type': 'application/json', }; final response = await http.get( Uri.parse('http://ikseer.onrender.com/orders/cart/'), headers: headers, followRedirects: false, // 禁用自动重定向 ); debugPrint('响应状态码: ${response.statusCode}'); debugPrint('响应内容: ${response.body}'); if (response.statusCode == 200) { final res = jsonDecode(response.body); await SharedPreferencesManager.storeStringVal( LocalStorageConstants.cartId, res['id']); return List<dynamic>.from(res['items']); } else if (response.statusCode == 401) { throw Exception(response.body); } else if (response.statusCode >= 300 && response.statusCode < 400) { // 手动处理重定向 final redirectUrl = response.headers['location']; if (redirectUrl != null) { final redirectResponse = await http.get(Uri.parse(redirectUrl), headers: headers); if (redirectResponse.statusCode == 200) { final res = jsonDecode(redirectResponse.body); await SharedPreferencesManager.storeStringVal( LocalStorageConstants.cartId, res['id']); return List<dynamic>.from(res['items']); } else { throw Exception('重定向失败,状态码: ${redirectResponse.statusCode}'); } } else { throw Exception('响应中未找到重定向地址'); } } else { throw Exception('服务器响应状态码: ${response.statusCode}'); } } }
内容的提问来源于stack exchange,提问作者Muhammed Ashraf Al-Arabi
相关产品推荐
相关产品推荐

