idhttp POST的坑

从其它平台迁移而来 坑 最近要和一个平台提供的http接口进行对接,由于服务不是部署在公网上的,所以没办法直接在开发环境下直接调试,又不能在客户的测试机上部署开发环境,只能选择加日志这种古老的方法。 在对接过程中却出现了莫名其妙的问题:POST的内容是一样的,但返回的内容却不一样,更准确点说是有的接口返回正常有的返回不正常(其实还是测试有限,测试多的话还会出现同一接口有的请求正常有的不正常)。 平台提供的word接口文档写得真的是……一言难尽,由此也对接口的准确性、可靠性等保持怀疑。不过,这次用我们提供的数据,平台方给出了相应的中间结果(中间结果一致)及返回结果,还有postman和curl的测试截图,充分证明接口以及数据请求是没有问题的。 在客户测试机上装了curl测试也证明接口没问题。(问为什么一开始没想到用curl?因为windows默认没有,而且utf8还会显示乱码,习惯性的就没想起来用) 请求头也改了,没用一样的效果。 最后实在找不出问题,就只能进行TCP抓包了,这一抓还就真抓出问题了: 原始数据 1 /knwRBV5D4Qtk7RzoQhtBUSMXQig3zURYmeSQBB17NVr6qddCkTxS7e0oO/qfNCkuX14vGsxEoLLN4KS5vtQWDs5on+GeAE5LadCZuHDCe7M25GitNKqnsCfC5qVmti1LyxLxYg2JpLP6GylWERWBOmbP2yO2Aiuey6V526rlRICnidM1W0A4ziNMSjGCng0n5Md4so/RjswNdcE4C5F0kBEGRWH0ZK+QdkZMs4zL84Pu/aiSMpiID9Mm+jtdLZuk0m0UtEd1MmxnU2KPdQz9057JAtM5LIj4YenZl3J86OPWtb9DE6a+410CWBawZY1vItZ+43Kh/QPnkw6Qe4toXRnF84X/ijtiWkTt4moJT87xDpf/TXEd7LRkddWPRRGF3KHnUKacLySwMmXkU6CQMazE1Kh1ZGML6zl1weaq4xVulFwhGfp2XKzYdZfT3uq4yqVr30AaEqYoy2/P1MkhTs5on+GeAE54r939gdklpefguipLJVBpWk/B5S9QsCDxDbfGYNxJo3rIAxDL7sjjlmVL1RjU86sHsNIbmRii7dL70pf5qcIMJzryGmtn94SAE2HjLw0abfr0A9amRsdIzs5on+GeAE5RIxdCKDfNRFnPqLzNU5stMSDcpuafJpNhUXDbQOMlPungXJHHZAgbE2XtoI4geIRYjiyBLDMQuB0l5WvfDhpRnYo1VaEu7J0tRuezwUplK61p4I8giLwAtO+yNMRV+J65g9XaT8vmf8gxmtK3wEFrve7HwsYH0QhlQQiMilY/JVsiHZS6+ID/w== 发送后抓到的却是 1 /knwRBV5D4Qtk7RzoQhtBUSMXQig3zURYmeSQBB17NVr6qddCkTxS7e0oO/qfNCkuX14vGsxEoLLN4KS5vtQWDs5on+GeAE5LadCZuHDCe7M25GitNKqnsCfC5qVmti1LyxLxYg2JpLP6GylWERWBOmbP2yO2Aiuey6V526rlRICnidM1W0A4ziNMSjGCng0n5Md4so/RjswNdcE4C5F0kBEGRWH0ZK+QdkZMs4zL84Pu/aiSMpiID9Mm+jtdLZuk0m0UtEd1MmxnU2KPdQz9057JAtM5LIj4YenZl3J86OPWtb9DE6a+410CWBawZY1vItZ+43Kh/QPnkw6Qe4toXRnF84X/ijtiWkTt4moJT87xDpf/TXEd7LRkddWPRRGF3KHnUKacLySwMmXkU6CQMazE1Kh1ZGML6zl1weaq4xVulFwhGfp2XKzYdZfT3uq4yqVr30AaEqYoy2/P1MkhTs5on+GeAE54r939gdklpefguipLJVBpWk/B5S9QsCDxDbfGYNxJo3rIAxDL7sjjlmVL1RjU86sHsNIbmRii7dL70pf5qcIMJzryGmtn94SAE2HjLw0abfr0A9amRsdIzs5on+GeAE5RIxdCKDfNRFnPqLzNU5stMSDcpuafJpNhUXDbQOMlPungXJHHZAgbE2XtoI4geIRYjiyBLDMQuB0l5WvfDhpRnYo1VaEu7J0tRuezwUplK61p4I8giLwAtO+yNMRV+J65g9XaT8vmf8gxmtK3wEFrve7HwsYH0QhlQQiMilY/JVsiHZS6+ID/w=%3D 最后的=被转码为%3D了! 解决 找到原因就好办了 1 2 //idhttp.HTTPOptions := [hoForceEncodeParams]; //默认强制对参数进行转码 idhttp.HTTPOptions := []; //去掉就OK了

2022-07-12 21:47:37 · 1 分钟 · 慢步道人

安装 CodeTyphon

从其它平台迁移而来 一直想找个开源的可以商用的Delphi的替代品,能跨平台了最好。开始时试过Lazarus,和D7还真是挺像的,不过用惯了XE,还是想找个习惯相似的IDE,扒拉下论坛后发现了CodeTyphon,就想着试一下。 下载 下载就不多说了,网上很容易找到,而且官方wiki写得也很好,英文好的可以直接看,像我这样的英语渣渣,还是有必要慢慢去啃的。 CodeTyphon下载后只有一个CodeTyphonIns.zip的压缩包,无论是Windows、Linux还是MacOS,安装包都是它,因为不管在哪个平台上安装,都是要编译的。 安装 解压CodeTyphonIns.zip得到CodeTyphonIns 在Windows平台,以管理员方式运行install.bat;在类unix平台,先cd CodeTyphonIns,再sudo ./install.sh 出现以下界面,输入0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ==================================================== CodeTyphon Studio Version 7.30 (GEN 7) Installation for Linux-Solaris-Openindiana-MacOS FreeBSD-NetBSD-OpenBSD-DragonFly ==================================================== -----WARNING------ WARNING ----WARNING------- You tryng to install CT as root This is NOT the correct procedure. You MUST start CodeTyphon Installation as normal user with sudo root privileges --------------------------------------------- 0) Install CodeTyphon Studio (remove old first) 1) Update CodeTyphon Studio 2) Remove CodeTyphon Studio 9) Exit >>> Select an action (press 0....

2021-02-07 09:29:48 · 1 分钟 · 慢步道人

自学RTC——DualServer

从其它平台迁移而来 在窗体上放4个TRtcHttpServer,依次设置ServerPort为:80、443、8080和8090,并分别命名为HS80、HS443、HS8080和HS8090 再放3个TRtcDualDataServerLink到窗体上,分别命名为DL80and443、DL8080and8090和DLall 设置DL80and443的Server属性为HS80,Server2属性为HS443;设置DL8080and8090的Server属性为HS8080,Server2属性为HS8090 设置DLall的Link属性为DL80and443,Link2属性为DL8080and8090 再放1个TRtcDataProvider到窗体上,设置Link属性为DLall,并在OnCheckRequest事件里写上代码: 1 2 3 4 5 with TRtcDataServer(Sender) do begin Accept; Write('you are on Server ' + ServerPort); end; 在窗口OnShow事件里启动所有TRtcHttpServer,在OnClose事件里停止所有TRtcHttpServer 编译运行 在浏览器里分别访问http://localhost:80、http://localhost:443、http://localhost:8080、http://localhost:8090 注意:TRtcDualDataServerLink只能选择设置Server*或Link*!

2020-11-22 14:54:39 · 1 分钟 · 慢步道人

RTC组件关系图

从其它平台迁移而来

2020-11-10 21:26:27 · 1 分钟 · 慢步道人

自学RTC——BrowserUpload

从其它平台迁移而来 核心代码 OnCheckRequest事件中的代码: 1 2 3 with TRtcDataServer(Sender) do if Request.FilePath.Equal(0, 'UPLOAD') then Accept; OnDataReceived事件中的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 var fname: string; cnt: integer; begin with TRtcDataServer(Sender) do begin if Request....

2020-11-10 20:04:07 · 2 分钟 · 慢步道人

自学RTC——ServerLesson4

从其它平台迁移而来 对于上节的示例中,比较适合发送小文件,若直接用于发送大文件的话,很容易把服务器的内存资源耗尽。当请求大文件时,可以限制每次发送大文件时使用的内存大小(例如16000 B)。 打开上节的工程 修改RtcDataProvider3的OnCheckRequest事件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var fname: string; begin with TRtcDataServer(Sender) do begin fname := GetFullFileName(Request.FileName); if (fname <> '') and (File_Exists(fname)) then begin Accept; Request.Info['fname'] := fname; Response.ContentLength := File_Size(fname); WriteHeader; end; end; end; 修改RtcDataProvider3的OnDataReceived事件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var fname: string; len: cardinal; begin with TRtcDataServer(Sender) do if Request....

2020-11-07 23:47:54 · 2 分钟 · 慢步道人

自学RTC——ServerLesson3

从其它平台迁移而来 /test.txt 打开上节的工程 添加组件RtcDataProvider3并设置Server属性为RtcHttpServer1,设置CheckOrder属性为900,使得RtcDataProvider3所处理的请求在其它请求之后(CheckOrder越小越先处理) 在当前exe所在路径下创建一个data文件夹,并在该文件夹内新建一个有内容的test.txt,然后编写一个GetFullFileName函数,用于从请求中提取文件名并转化为本地文件名 1 2 3 4 5 6 7 8 9 10 11 12 13 function GetFullFileName(fname: string): string; var DocRoot: string; begin DocRoot := ExtractFilePath(AppFileName); if Copy(DocRoot, length(DocRoot), 1) = '\' then Delete(DocRoot, length(DocRoot), 1); DocRoot := DocRoot + '\data'; fname := StringReplace(fname, '/', '\', [rfreplaceall]); Result := ExpandFileName(DocRoot + fname); if UpperCase(Copy(Result, 1, length(DocRoot))) <> UpperCase(DocRoot) then Result := ''; end; 在RtcDataProvider3的OnCheckRequest事件中写上代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 var fname: string; begin with TRtcDataServer(Sender) do begin fname := GetFullFileName(Request....

2020-11-07 20:27:36 · 1 分钟 · 慢步道人

自学RTC——ServerLesson2

从其它平台迁移而来 /SQUARE 打开上节的工程 添加组件RtcDataProvider2并设置Server属性为RtcHttpServer1 在RtcDataProvider2的OnCheckRequest事件中写上代码: 1 2 3 with TRtcDataServer(Sender) do if UpperCase(Request.FileName)='/SQUARE' then Accept; 在RtcDataProvider2的OnDataReceived事件中写上代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var line:integer; begin with TRtcDataServer(Sender) do if Request.Complete then begin Write('<html><body>'); Write('Here comes a table of square values ... <br>'); for line:=1 to 100 do begin // 使用3个 write 和使用1个效果是一样的 Write('Square of '+IntToStr(line)+' = '); Write(IntToStr(line*line)); Write('<br>'); end; Write('....

2020-11-05 23:34:37 · 1 分钟 · 慢步道人

自学RTC——ServerLesson1

从其它平台迁移而来 RTC全称RealThinClient,据说是Delphi做三层的神器之一,虽然听说已久,却始终未好好研究过,而且安装包里带的有示例源码,于是乎,索性拿这些源码开这么个系列,督促下自己。 步骤 创建一个新工程 从RTC Server组件页中找到RtcHttpServer组件放到窗体上 设置RtcHttpServer1的ServerPort属性为80 在窗体的OnCreate事件里写上代码: 1 RtcHttpServer1.Listen; 从RTC Server组件页中找到RtcDataProvider组件放到窗体上 设置RtcDataProvider1的Server属性为RtcHttpServer1 在RtcDataProvider1的OnCheckRequest事件中写上代码: 1 2 3 with Sender as TRtcDataServer do if UpperCase(Request.FileName)='/TIME' then Accept; 在RtcDataProvider1的OnDataReceived事件中写上代码: 1 2 3 with Sender as TRtcDataServer do if Request.Complete then Write('Current time is: '+TimeToStr(Now)); 编译并运行 打开浏览器,访问网址http://localhost/time 示例源码 核心源码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 procedure TForm1....

2020-11-05 20:51:13 · 2 分钟 · 慢步道人

FireDAC的数据连接池

从其它平台迁移而来 之前就想搞个数据连接池,结果太麻烦就放弃了,不想却在TFDConnection中看到了Pooled属性,就一路挖了下来,还真就是那么回事! TFDManager 之前只知道,放上TFDManager控件后,什么都不用做,就可以在别的单元引用该单元后直接连接到TFDConnection控件了;现在,数据连接池还是要通过TFDManager来实现。 设置数据连接池参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //指定动态库 FDPhysMySQLDriverLink.VendorLib := 'libmysql.dll'; //设置连接参数 with FDManager.ConnectionDefs.AddConnectionDef do begin Name := 'MySQL_Conn'; Params.DriverID := 'MySQL'; Params.Add('CharacterSet=csUtf8mb4'); Params.Add('Server=127.0.0.1'); Params.Add('Port=3306'); Params.Database := 'test'; Params.UserName := 'root'; Params.Password := '123456'; Params.PoolMaximumItems := 10; Params.Pooled := True; end; 以上是以MySQL为例,其它数据库参照即可。 打开连接池 1 FDManager.Open; 获取连接 1 2 FDConnection.ConnectionDefName := 'MySQL_Conn'; FDConnection.Connected := True; 归还连接 FDConnection直接放到窗体上,或动态创建,写上如下代码即可,无需在设计器里设置任何东西。...

2020-08-11 21:59:09 · 1 分钟 · 慢步道人