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的请求配置中:
注:如果是需要登录态的接口,Cookie中包含会话凭证,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', },
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
相关产品推荐
相关产品推荐

