Delphi 3.0中使用HTTP POST和GET实现表单提交与数据获取
基于Delphi 3.0实现注册表单的POST/GET请求处理问题
本人使用Borland Delphi 3.0(无Indy的TIdHTTP组件),需要为程序《Radio Calculator v3.50》实现以下功能:
- POST提交
Username、Email、Phone number、JPG文件四个参数,Web端PHP结合Microsoft Access MDB数据库生成对应Username的KEY - 15分钟后通过GET从Web端获取该用户的
Username和KEY
现提出三个技术问题:
- 如何在Delphi 3.0的HTTP组件中实现上述POST和GET请求(包含四个参数)?如何处理请求结果、存储结果变量用于后续逻辑?
- 该实现流程是否存在安全漏洞?
- 当前POST提交后延迟GET的流程是否有遗漏?是否需改为即时GET?是否改用
TWebBrowser组件更合适?
附本人已实现的TIdHTTP.Post()与PHP交互代码:
procedure TForm1.Button1Click(Sender: TObject); Var params : TStringList; res : TStringStream; begin params := TStringList.Create; params.Add('a='+'hello'); res := TStringStream.Create(''); idhttp1.Post('http://localhost/test/hallo.php', params, res); ShowMessage(res.DataString); res.Free; params.Free; end;
<?php echo $_POST['a']; ?>
问题1:Delphi 3.0下实现POST/GET请求(含文件上传)
Delphi 3.0自带THTTP组件(在Internet组件页),原生组件不直接支持含文件的多表单POST,需手动构造multipart/form-data格式请求体:
1.1 POST请求(含文件)实现代码
function PostWithFile(const URL, Username, Email, Phone, JPGFilePath: string): string; var HTTP: THTTP; Boundary, Content: string; JPGStream: TFileStream; PostStream: TMemoryStream; begin Result := ''; // 生成随机边界符 Boundary := '----Delphi3PostBoundary_' + IntToStr(GetTickCount); PostStream := TMemoryStream.Create; JPGStream := TFileStream.Create(JPGFilePath, fmOpenRead or fmShareDenyWrite); HTTP := THTTP.Create(nil); try // 构造文本参数 Content := '--' + Boundary + #13#10; Content := Content + 'Content-Disposition: form-data; name="Username"' + #13#10#13#10; Content := Content + Username + #13#10; Content := Content + '--' + Boundary + #13#10; Content := Content + 'Content-Disposition: form-data; name="Email"' + #13#10#13#10; Content := Content + Email + #13#10; Content := Content + '--' + Boundary + #13#10; Content := Content + 'Content-Disposition: form-data; name="Phone number"' + #13#10#13#10; Content := Content + Phone + #13#10; // 构造文件参数 Content := Content + '--' + Boundary + #13#10; Content := Content + 'Content-Disposition: form-data; name="JPGFile"; filename="' + ExtractFileName(JPGFilePath) + '"' + #13#10; Content := Content + 'Content-Type: image/jpeg' + #13#10#13#10; PostStream.WriteBuffer(Content[1], Length(Content)); // 写入JPG文件内容 PostStream.CopyFrom(JPGStream, JPGStream.Size); // 结束边界 Content := #13#10'--' + Boundary + '--'#13#10; PostStream.WriteBuffer(Content[1], Length(Content)); // 设置HTTP请求头 HTTP.Request.ContentType := 'multipart/form-data; boundary=' + Boundary; HTTP.Request.ContentLength := PostStream.Size; PostStream.Position := 0; // 发送POST请求并获取结果 Result := HTTP.Post(URL, PostStream); // 存储结果到配置文件(示例) with TStringList.Create do try Add('PostResult=' + Result); SaveToFile('RegResult.ini'); finally Free; end; finally HTTP.Free; JPGStream.Free; PostStream.Free; end; end;
1.2 GET请求实现代码
// 全局变量存储结果 var GlobalUsername, GlobalKey: string; function GetUserKey(const URL, Username: string): string; var HTTP: THTTP; RequestURL: string; begin Result := ''; HTTP := THTTP.Create(nil); try // 构造带URL编码参数的GET地址 RequestURL := URL + '?Username=' + HTTP.URLEncode(Username); Result := HTTP.Get(RequestURL); // 解析结果(假设返回格式为"Username:xxx|KEY:xxx") with TStringList.Create do try Delimiter := '|'; DelimitedText := Result; GlobalUsername := Copy(Strings[0], Pos(':', Strings[0])+1, Length(Strings[0])); GlobalKey := Copy(Strings[1], Pos(':', Strings[1])+1, Length(Strings[1])); finally Free; end; finally HTTP.Free; end; end;
问题2:流程中的安全漏洞
- 明文传输风险:Delphi 3.0原生
THTTP不支持HTTPS,所有数据(用户名、邮箱、KEY)均明文传输,极易被拦截窃取。 - SQL注入风险:Web端PHP若未对参数做合法性校验,Access MDB仍存在注入漏洞,可能导致数据库被篡改或泄露。
- 身份验证缺失:POST和GET请求无身份校验,攻击者可伪造请求提交数据或窃取他人KEY。
- 文件上传风险:Web端若未限制JPG文件的大小、格式,可能被上传恶意文件,导致服务器入侵。
问题3:流程遗漏与组件选择
流程遗漏
- POST提交后,Web端应返回唯一请求Token,而非仅依赖Username查询KEY——重名用户会导致查询错误。
- 15分钟延迟GET需用
TTimer组件实现计时,同时要处理网络异常,增加重试机制。
是否改为即时GET?
若Web端KEY生成可同步完成,建议在POST响应中直接返回KEY,避免延迟等待的不确定性,减少一次HTTP请求。仅当KEY生成是异步耗时操作(如人工审核)时,才需要延迟GET。
是否改用TWebBrowser组件?
不推荐:
- 封装IE内核,体积大、启动慢,依赖系统IE版本,兼容性差。
- 表单提交和结果解析复杂度远高于原生HTTP组件,不易自动化处理。
- 无法灵活控制请求头、超时等参数,错误处理难度高。
内容的提问来源于stack exchange,提问作者Ian adhi
相关产品推荐
相关产品推荐

