DataSnap REST JavaScript客户端 - 如何显示从TServerMethods方法返回为TStream的pdf文件数据

时间:2014-09-05 11:46:24

标签: javascript delphi datasnap tstream

我有一个DataSnap服务器方法

function TServerMethods.GetFile(filename): TStream

返回一个文件。 在我的测试用例中,该文件是一个简单的.PDF。

我确信这个功能运行正常,因为我能够在ObjectiveC客户端应用程序上打开文件,我已经使用自己的http调用DataSnap方法(没有Delphi代理)。 从ASIHttpRequest对象读取流并保存为本地文件,然后在标准pdf阅读器中加载和定期显示。 我不知道ASIHttpRequest究竟是如何管理返回的数据的。

但是在我使用标准

的JavaScript客户端
stream = ServerMethods().GetFile('test.pdf')

JavaScript函数,由DataSnap代理本身提供,我不知道如何向用户显示.pdf数据。

使用

window.open().document.write(stream);

打开一个新的浏览器窗口,其中包含文本原始数据(%PDF-1.5%â€1 0 obj<< / Type / Catalog / Pages 2 0 R ...... ..)

使用

window.open("data:application/pdf;base64," +stream);

我得到一个空的新浏览器页面。

window.open("data:application/pdf," +stream);

document.location = 'data:application/pdf,'+encodeURIComponent(serverMethods().GetFile('test'));

我得到一个带有pdf empry阅读器的新浏览器页面并提醒“此PDF文档无法正确显示”

没有任何改变添加:

GetInvocationMetadata().ResponseContentType := 'application/pdf';

进入DataSnap函数。

我没有其他想法......

修改

该任务用于一般文件下载,而不仅仅是PDF。 PDF仅供测试。 GetFile必须管理.pdf,.xlsx,.docx,.png,.eml等......

1 个答案:

答案 0 :(得分:1)

设置ResponseContentType后,服务器端代码将按预期工作。您可以直接从浏览器调用该方法来测试它。更改班级名称以匹配您正在使用的班级名称:

http://localhost:8080/datasnap/rest/TServerMethods1/GetFile/test.pdf

我确定可以在浏览器端正确显示流,但我不确定那是什么。除非您对流做了一些特别的事情,否则我建议您直接获取文档或使用网络操作并退出浏览器。基本上是mjn建议的。

我可以想到几个解决方案。

1)快速的方法是允许直接访问文档。

在WebFileDispatcher中,添加WebFileExtension。选择.pdf,它会为你填写mime类型。假设您的pdf文档位于" docs"文件夹,网址可能如下所示:

http://localhost:8080/docs/test.pdf

2)我可能会在网络模块上添加一个动作。它涉及的更多,但它也让我有更多的控制权。

使用此网址:

http://localhost:8080/getfile?filename=test.pdf

在web动作处理程序中这样的代码(没有检查或错误处理)。 Content-Disposition标头建议下载文件的文件名:

procedure TWebModule1.WebModule1GetFileActionAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  lStream: TMemoryStream;
  lFilename: string;
begin
  lFilename := Request.QueryFields.Values['filename'];
  lStream := TMemoryStream.Create;
  lStream.LoadFromFile('.\Docs\' + lFilename);
  lStream.Position := 0;
  Response.ContentStream := lStream;
  Response.ContentType := 'application/pdf';
  Response.SetCustomHeader('Content-Disposition',
    Format('attachment; filename="%s"', [lFilename]));
end;