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

如何通过Delphi TREST组件向REST API上传PDF文件?

Delphi通过REST API上传PDF文件失败排查

我用Delphi代码向REST API上传PDF文件,使用的AttachDocument过程代码如下:

procedure AttachDocument(pathFile : String);
  var 
    RESTClient : TRESTClient;
    RESTRequest : TCustomRESTRequest; 
    Response : TCustomRESTResponse;
  begin
    RESTClient := TRESTClient.Create('');
    try
      RESTRequest := TCustomRESTRequest.Create(nil);
      try
        RESTClient.BaseURL('api_url');
        RESTRequest.Client := RESTClient;
        RESTRequest.Accept := 'application/json';
        RESTRequest.Params.AddHeader('j_token','mytoken').Options := 1; //This is adding poDoNotEncode
        RESTRequest.Method := rmPOST;
        RESTRequest.AddParameter('file',pathFile,pkFILE,1); // Same as above 1 = poDoNotEncode
        //RESTRequest.AddFile(pathFile, ctAPPLICATION_PDF);
        RESTRequest.Execute;
        Response := RESTRequest.Response;
        ShowMessage(Response.Content);
      finally
        RESTRequest.Free;
      end;
    finally
      RESTClient.Free;
    end;
  end;

由于项目限制只能使用无参数名的AddFile方法,所以改用AddParameter指定参数名为'file',但目标API返回错误:{"errors":"no files found"}。

API提供者提供的C#示例代码如下:

var client = new RestClient("api_url");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "multipart/form-data");
request.AddHeader("v", "4.2");
request.AddHeader("j_token", "histoken");
request.AddFile("file", "/C:/Users/olivm/Documents/QA API Swagger/smartpacte2.pdf", "application/.pdf");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

对比代码后没发现明显差异,于是用本地Flask API测试,请求返回显示收到了ImmutableMultiDict格式的'file'参数,包含FileStorage对象,和Postman测试结果类似。但用Webhook测试时,代码上传的请求没有文件,Postman则正常。现在有两个疑问:

  1. 本地Flask API是否确实收到了文件?
  2. 为何Webhook无法接收?

问题分析与解决

关于本地Flask API是否收到文件

Flask返回的ImmutableMultiDict包含FileStorage对象,说明确实收到了文件。FileStorage是Flask处理上传文件的标准对象,只有当请求包含合法文件流时才会生成,和Postman结果一致也能佐证这一点。

Webhook无法接收的原因及解决思路

  1. 未显式指定Content-Type头
    C#代码明确添加了Content-Type: multipart/form-data头,但Delphi代码未设置。尽管TCustomRESTRequest在添加pkFILE类型参数时会自动切换到multipart/form-data,但部分严格的API/Webhook要求显式声明,否则会解析失败。
    解决:在Delphi代码中添加:

    RESTRequest.AddHeader('Content-Type', 'multipart/form-data');
    
  2. 缺失文件MIME类型
    C#的AddFile指定了文件MIME类型(虽写法有误,正确应为application/pdf),但Delphi的AddParameter未指定。部分API会校验MIME类型,缺失可能被判定为无效文件。
    解决:用重载方法指定MIME类型:

    RESTRequest.AddParameter('file', pathFile, pkFILE, ctAPPLICATION_PDF, [poDoNotEncode]);
    
  3. 参数选项写法不规范
    代码用Options := 1设置poDoNotEncode,虽数值正确,但更稳妥的是用枚举集合写法,避免枚举定义变化引发问题:

    RESTRequest.Params.AddHeader('j_token','mytoken').Options := [poDoNotEncode];
    RESTRequest.AddParameter('file', pathFile, pkFILE, [poDoNotEncode]);
    
  4. 文件路径编码问题
    若路径含非ASCII字符,poDoNotEncode可能导致路径解析错误,文件无法被正确读取上传。可检查路径是否有特殊字符,或尝试使用UTF-8编码的绝对路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:50:25