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

Flutter调用Odoo JSON-RPC API返回404但Postman请求正常

Flutter请求Odoo JSON-RPC接口返回404但Postman成功的排查方案

核心问题分析

同样的请求在Postman中成功但Flutter中返回404,通常是请求细节不一致导致的,以下是具体排查方向和解决办法:


1. 补全JSON-RPC请求格式

Odoo的JSON-RPC接口严格遵循2.0规范,要求请求体必须包含id字段(整数类型),你的代码中缺少该字段,这很可能是服务器拒绝请求的核心原因。

修改请求体:

Map<String, dynamic> requestBody = {
  "jsonrpc": "2.0",
  "method": "call",
  "id": 1, // 新增必填的id字段,值可以是任意整数
  // 若接口需要业务参数,需补充"params": {...}结构
};

2. 对齐请求头差异

Postman会自动添加多个默认请求头(比如Cookie、Accept-Encoding、Cache-Control等),而你的Flutter代码只配置了少数几个头。如果服务器依赖这些头做校验,就会返回404。

解决办法:

  • 打开Postman的请求详情页,复制所有请求头
  • 将这些头完整添加到Flutter的请求配置中:
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'User-Agent': 'YourAppName/1.0.0',
      'Cookie': 'xxx=xxx; yyy=yyy', // 替换为Postman中实际的Cookie值
      'Accept-Encoding': 'gzip, deflate, br',
      'Cache-Control': 'no-cache',
    },
    
    注:如果是需要登录态的接口,Cookie中包含会话凭证,Flutter请求必须携带才能通过服务器校验。

3. 校验URL一致性

确认Flutter代码中的URL和Postman中的完全一致,重点检查:

  • 末尾是否带斜杠(比如Postman用https://odoo18.ts.com.ps/public/splash/,代码里少了最后一个/)
  • 是否存在隐藏的编码差异(比如特殊字符的转义处理)

验证方法:
在Flutter中打印完整请求URL,和Postman的URL逐字符对比。

4. 显式开启重定向处理

Postman默认自动跟随3xx重定向,Flutter的http.post默认也支持,但可以显式设置确保生效:

final response = await http.post(
  url,
  headers: {...},
  body: json.encode(requestBody),
  followRedirects: true, // 显式开启重定向
  maxRedirects: 5, // 设置最大重定向次数
);

修改后的完整示例代码

Future fetchOnBoardingData() async {
  final url = Uri.parse("https://odoo18.ts.com.ps/public/splash");

  print('Requesting URL: $url');

  try {
    Map<String, dynamic> requestBody = {
      "jsonrpc": "2.0",
      "method": "call",
      "id": 1, // 新增id字段
    };

    final response = await http.post(
      url,
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'User-Agent': 'YourAppName/1.0.0',
        // 补充Postman中的其他请求头
        'Cookie': 'xxx=xxx', // 替换为实际Cookie
        'Accept-Encoding': 'gzip, deflate, br',
      },
      body: json.encode(requestBody),
      followRedirects: true,
    );

    print('Response status: ${response.statusCode}');
    print('Response body: ${response.body}');

    if (response.statusCode == 200) {
      Map<String, dynamic> responseData = json.decode(response.body);
      if (responseData.containsKey('result')) {
        List data = responseData['result'];
        var categories = data.map((cat) => OnBoardingModel.fromJson(cat)).toList();
        return {'data': categories};
      } else {
        throw ServerException('Error in RPC response: ${responseData['error']}');
      }
    } else {
      throw ServerException('Failed to load Home Data, status code: ${response.statusCode}, response: ${response.body}');
    }
  } on SocketException {
    throw NoInternetException();
  } catch (e) {
    print('Failed to fetch Home Data: $e');
    throw UnknownException('Failed to fetch Home Data: $e');
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:53:11