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

使用THTTPClient.Post重载方法时触发参数错误异常排查

Delphi THTTPClient.Post重载调用异常问题解决

问题描述

使用Delphi的THTTPClient.Post方法时,调用重载idhttp.Post(url,data,jsontoget,nil,heads)可正常获取响应,但调用idhttp.Post(url,data,jsontoget)时触发ENetHTTPClientException异常,错误提示:

Project Project1.exe raised exception dass ENetHTTPClientException with message Error sending data: (87)parameter error

调试发现异常发生在System.Net.HttpClient.THTTPClient.ExecuteHTTPInternal方法的DoExecuteRequest调用阶段。

相关核心代码片段:

var
  url,str:string;
  JsonToSend,jsontoget: TStringStream;
  data:Tstrings;
  LHeaders: array of TNameValuePair; 
  IdHttp :THTTPClient;
begin
  url:='http://*******/getPsnByCondition';
  IdHttp:=THTTPClient.Create;
  idhttp.Accept:='application/json,text/plain,*/*';
  idhttp.AcceptCharSet:='utf-8'  ;
  idhttp.AcceptEncoding:='gzip,deflate';
  idhttp.AcceptLanguage:='zh-CN,zh;q=0.9';
  idhttp.ContentType:='application/x-www-form-urlencoded; charset=UTF-8';
  idhttp.UserAgent:='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36';
  idhttp.CustomHeaders['Cookie'] :='XSRF-TOKEN='+edt2.Text+';SESSION='+edt1.Text;
  idhttp.CustomHeaders['X-XSRF-TOKEN'] :=edt2.Text;
  idhttp.CustomHeaders['Host'] :='******';
  idhttp.CustomHeaders['Connection']:='keep-alive';
  idhttp.CustomHeaders['Content-Length:']:='177'; // 键名带多余冒号
  idhttp.CustomHeaders['Origin'] :='*****';
  idhttp.CustomHeaders['Referer'] :='http://******/N1412.html';

  data:=tstringlist.Create;
  data.Clear;
  data.Add('psnCertType=01');
  data.Add('certno=******');
  data.Add('searchInsuEmp=true');
  data.Add('menuQuryPerm=4');
  data.Add('_modulePartId_=');
  data.Add('fron_tUrl=http://********/N1412.html#/N141201');

  SetLength(heads, 8);
  heads[0] := TNameValuePair.Create('Cookie', 'XSRF-TOKEN='+edt2.Text+';SESSION='+edt1.Text);
  heads[1] := TNameValuePair.Create('X-XSRF-TOKEN', edt2.Text);
  heads[2] := TNameValuePair.Create('Host','*****');
  heads[3] := TNameValuePair.Create('Connection','keep-alive');
  heads[4] := TNameValuePair.Create('Content-Length','177'); // 键名无冒号
  heads[5] := TNameValuePair.Create('Origin','*****');
  heads[6] := TNameValuePair.Create('Referer','******/mbs/ui/N1412.html');
  heads[7] := TNameValuePair.Create('Accept-Encoding','gzip,deflate');

  jsontoget:= TStringStream.Create('',TEncoding.UTF8);
  jsontoget.Position:=0;
  // Post调用代码在此处
end;

问题分析

  1. Header键名不规范:CustomHeaders中设置Content-Length:时,键名多了一个冒号,违反HTTP Header规范,导致客户端请求参数解析错误。而带heads参数的重载中,Content-Length键名正确,因此可正常执行。
  2. 手动设置Content-Length风险:手动指定的Content-Length值(177)可能与data编码后的实际长度不匹配,THTTPClient本身会自动计算该值,手动设置反而引发请求格式错误。
  3. 重复Header设置冲突:同时在CustomHeaders和heads数组中重复设置Cookie、X-XSRF-TOKEN等Header,可能导致请求Header冗余或冲突,进一步触发异常。

解决方案

1. 移除手动设置的Content-Length Header

完全删除CustomHeaders和heads数组中关于Content-Length的设置,让THTTPClient自动计算并设置该Header,避免长度不匹配问题。

2. 修复Header键名错误

若需保留其他手动Header,确保键名符合HTTP规范,比如去掉Content-Length:中的冒号(更推荐直接移除该手动设置)。

3. 统一Header设置方式

选择一种方式设置Header,要么用CustomHeaders,要么用传入的heads参数,避免重复设置。示例代码(统一使用CustomHeaders):

var
  url,str:string;
  JsonToSend,jsontoget: TStringStream;
  data:Tstrings;
  IdHttp :THTTPClient;
begin
  url:='http://*******/getPsnByCondition';
  IdHttp:=THTTPClient.Create;
  try
    idhttp.Accept:='application/json,text/plain,*/*';
    idhttp.AcceptCharSet:='utf-8';
    idhttp.AcceptEncoding:='gzip,deflate';
    idhttp.AcceptLanguage:='zh-CN,zh;q=0.9';
    idhttp.ContentType:='application/x-www-form-urlencoded; charset=UTF-8';
    idhttp.UserAgent:='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36';
    idhttp.CustomHeaders['Cookie'] :='XSRF-TOKEN='+edt2.Text+';SESSION='+edt1.Text;
    idhttp.CustomHeaders['X-XSRF-TOKEN'] :=edt2.Text;
    idhttp.CustomHeaders['Host'] :='******';
    idhttp.CustomHeaders['Connection']:='keep-alive';
    idhttp.CustomHeaders['Origin'] :='*****';
    idhttp.CustomHeaders['Referer'] :='http://******/N1412.html';

    data:=tstringlist.Create;
    try
      data.Add('psnCertType=01');
      data.Add('certno=******');
      data.Add('searchInsuEmp=true');
      data.Add('menuQuryPerm=4');
      data.Add('_modulePartId_=');
      data.Add('fron_tUrl=http://********/N1412.html#/N141201');

      jsontoget:= TStringStream.Create('',TEncoding.UTF8);
      try
        // 调用不带heads参数的Post重载
        idhttp.Post(url,data,jsontoget);
        // 此处添加响应处理逻辑
      finally
        jsontoget.Free;
      end;
    finally
      data.Free;
    end;
  finally
    IdHttp.Free;
  end;
end;

4. 确保资源正确释放

添加try...finally块,保证THTTPClient、TStringStream、TStrings等资源被正确释放,避免内存泄漏或资源占用问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:04:51