Python requests请求转Flutter时提示ParamList不存在如何解决
问题背景

使用Python编写的requests请求代码可正常运行,调用目标接口后可得到上述截图所示的正常响应。
现需要将该请求逻辑迁移至Flutter端实现,首次编写的Dart请求代码如下:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:html/parser.dart'; import 'package:dio/dio.dart'; void main() async { var url = 'https://www.lottecinema.co.kr/LCWS/Ticketing/TicketingData.aspx'; var dic = { "paramList": { "MethodName": "GetPlaySequence", "channelType": "HO", "osType": "W", "osVersion": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", "playDate": "2022-06-29", "cinemaID": "1|0001|1013", "representationMovieCode": "" } }; var req = await Dio().post( '$url', data: dic, ); print(req); runApp(const MyApp()); }
运行上述代码后接口返回韩文错误ParamList가 존재하지 않습니다,对应含义为ParamList does not exist.(ParamList参数不存在),报错截图如下:
之后尝试第二种实现方案,代码如下:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:html/parser.dart'; import 'package:dio/dio.dart'; void main() async { var url = 'https://www.lottecinema.co.kr/LCWS/Ticketing/TicketingData.aspx'; var dic = { "paramList": { "MethodName": "GetPlaySequence", "channelType": "HO", "osType": "W", "osVersion": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", "playDate": "2022-06-29", "cinemaID": "1|0001|1013", "representationMovieCode": "" }.toString() }; var request = await http.MultipartRequest('Post', Uri.parse('$url')); request.fields.addAll(dic); http.StreamedResponse response = await request.send(); var responseString = await response.stream.bytesToString(); print("STATUS CODE : ${response.statusCode}"); print("RESPONSE BODY : ${responseString}"); runApp(const MyApp()); }
该版本代码依然无法得到正确的接口响应,运行结果截图如下:
接口要求的paramList参数格式、预期响应结果参考如下截图:

解决方案
报错核心原因是请求参数格式和Python requests默认发送的表单格式不匹配。该.NET接口要求paramList字段的值是标准JSON序列化后的字符串,且请求要使用application/x-www-form-urlencoded格式提交,不能直接传嵌套Map,也不能用Dart默认的Map toString()方法——Dart的Map toString()输出的是{key: value}格式,不是标准JSON结构。
可直接运行的Dio实现代码
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; void main() async { var url = 'https://www.lottecinema.co.kr/LCWS/Ticketing/TicketingData.aspx'; // 内层参数先序列化为标准JSON字符串,作为paramList的字段值 var formData = { "paramList": jsonEncode({ "MethodName": "GetPlaySequence", "channelType": "HO", "osType": "W", "osVersion": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", "playDate": "2022-06-29", "cinemaID": "1|0001|1013", "representationMovieCode": "" }) }; var req = await Dio().post( url, data: formData, options: Options( contentType: Headers.formUrlEncodedContentType, headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" } ), ); print(req.data); runApp(const MyApp()); }
关键调整点
- 不要直接传嵌套Map给请求体:Dio默认会把嵌套Map序列化为多层结构,而接口只接收一级表单字段
paramList,其值为JSON字符串 - 禁止用Dart的
Map.toString()生成JSON:该方法输出格式不符合JSON规范,必须使用dart:convert包的jsonEncode()方法做标准序列化 - 明确指定
contentType为application/x-www-form-urlencoded,和Python requests提交表单的默认格式保持一致 - 额外在请求头添加User-Agent模拟浏览器请求,避免被接口反爬策略拦截
内容的提问来源于stack exchange,提问作者jhlee
相关产品推荐
相关产品推荐

