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

Flutter使用Dio/Http发起Get请求遇401 Unauthorized问题求助

Flutter中带Token发起Get请求仍返回401 Unauthorized(Postman可正常请求)

以下是针对该问题的排查方向和解决方案:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:32:43