PHP中通过Curl发送请求负载:达纳蒙银行登录后POST请求问题
解决PHP Curl发送Danamon银行表单数据的问题
看起来你踩了一个常见的坑:把表单数据错误地序列化为JSON发送,但服务器实际期望的是multipart/form-data格式的表单请求,和浏览器发送的格式一致。下面是具体的解决方案:
核心问题分析
你之前用json_encode($data)把数据转成JSON字符串发送,但从浏览器开发者工具的请求来看,服务器接收的是标准的表单数据(带WebKit分隔符的multipart格式),而不是JSON payload。这就导致服务器无法正确解析你的请求。另外,请求方法是POST而不是PUT,form-data格式几乎都是用于POST请求的。
正确的实现步骤
1. 保留登录会话的Cookie
登录成功后,必须保存会话Cookie,否则后续请求会被服务器判定为未登录。Curl可以通过CURLOPT_COOKIEJAR和CURLOPT_COOKIEFILE来实现:
// 登录时设置Cookie保存路径 curl_setopt($loginCh, CURLOPT_COOKIEJAR, 'danamon_cookie.txt'); // 后续请求加载Cookie curl_setopt($ch, CURLOPT_COOKIEFILE, 'danamon_cookie.txt');
2. 构造表单数据数组(不要转JSON)
直接使用数组存储所有需要的字段,包括浏览器里看到的usercontrol字段(你之前的代码里漏掉了这个字段):
$data = [ 'usercontrol' => 'AcctMgmt/am_AcctSummaryNew_lst', '__EVENTTARGET' => $eventTarget, '__EVENTARGUMENT' => $eventArgument, '__LASTFOCUS' => '', '__VIEWSTATE' => $__VIEWSTATE, 'hdnActionCd' => '', 'hdnRandomKey' => '', 'hdnWUC' => 'AcctMgmt/am_AcctSummaryNew_lst', 'hdnLanguage' => $hdnLanguage, 'hdnPortlet' => '', 'Portlet1:hdnFunctionId' => '', '_ctl0:_ctl8:ddlExRate' => '1' ];
3. 配置Curl发送POST表单请求
直接把数组传给CURLOPT_POSTFIELDS,Curl会自动帮你生成正确的multipart/form-data格式(包括分隔符和Content-Type头):
$ch = curl_init('https://your-danamon-target-url.com'); // 加载登录Cookie curl_setopt($ch, CURLOPT_COOKIEFILE, 'danamon_cookie.txt'); // 设置为POST请求 curl_setopt($ch, CURLOPT_POST, true); // 直接传递表单数组,Curl自动处理multipart格式 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 跟随重定向(如果需要) curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 返回响应内容而不是直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 可选:模拟浏览器的User-Agent,避免被拦截 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'); // 执行请求 $response = curl_exec($ch); // 检查Curl错误 if (curl_errno($ch)) { die('Curl Error: ' . curl_error($ch)); } curl_close($ch);
关键注意事项
- 不要序列化JSON:服务器期望的是表单数据,不是JSON,直接传数组即可。
- 动态字段更新:
__VIEWSTATE、__EVENTARGUMENT这类字段是动态生成的,必须从之前的页面响应中实时获取,不能硬编码。 - 请求头模拟:部分银行网站会检查
Referer、User-Agent等请求头,建议从浏览器开发者工具中复制这些头信息,通过CURLOPT_HTTPHEADER添加到Curl请求中。
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

