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

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

现提出三个技术问题:

  1. 如何在Delphi 3.0的HTTP组件中实现上述POST和GET请求(包含四个参数)?如何处理请求结果、存储结果变量用于后续逻辑?
  2. 该实现流程是否存在安全漏洞?
  3. 当前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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:57:53