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

Delphi 10.4 DataSnap REST接口返回PDF被包装为JSON问题咨询

DataSnap REST服务返回PDF被序列化为JSON问题解决方案

问题根源

DataSnap默认会对服务端方法的所有返回值执行自动JSON序列化逻辑,你直接将TFileStream作为方法返回值时,序列化器会将流内的字节转换为整数数组,包装到标准{"result": [...]}的JSON结构中,即便你设置了正确的Content-Type响应头,实际响应体依然是JSON格式内容,因此会出现你遇到的问题。

修复方案

不要通过方法返回值传递文件流,直接操作调用元数据的响应流属性,跳过DataSnap的默认序列化逻辑,代码示例如下:

function TServerMethods1.GetPdf: Boolean;
var
  fStream: TFileStream;
  meta: TDSInvocationMetadata;
begin
  Result := False;
  meta := GetInvocationMetadata;
  try
    fStream := TFileStream.Create('images/ticket.pdf', fmOpenRead or fmShareDenyNone);
    // 直接绑定响应流,无需手动释放,DataSnap会在响应发送完成后自动回收
    meta.ResponseContentStream := fStream;
    meta.ResponseContentType := 'application/pdf';
    // 可选配置:控制客户端行为,inline为预览,attachment为直接下载
    meta.SetCustomHeader('Content-Disposition', 'inline; filename="ticket.pdf"');
    meta.ResponseCode := 200;
    Result := True;
  except
    on E: Exception do
    begin
      meta.ResponseCode := 500;
      meta.ResponseContentType := 'text/plain';
      meta.ResponseContent := '文件加载失败: ' + E.Message;
    end;
  end;
end;

额外注意事项

  • 你之前在WebModuleAfterDispatch中全局设置Content-Type的配置可以删除,该全局配置会影响其他正常返回JSON的接口,直接在方法内通过InvocationMetadata设置的响应参数优先级更高,只会作用于当前接口。
  • 不需要手动释放赋值给ResponseContentStream的流对象,DataSnap框架会在响应发送完成后自动执行释放操作,手动释放会导致响应发送时出现内存访问错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:36:03