DataSnap REST JavaScript客户端–如何显示从Tserver方法以TStream形式返回的pdf文件数据
我有一个DataSnap服务器方法DataSnap REST JavaScript客户端–如何显示从Tserver方法以TStream形式返回的pdf文件数据,javascript,delphi,datasnap,tstream,Javascript,Delphi,Datasnap,Tstream,我有一个DataSnap服务器方法 function TServerMethods.GetFile(filename): TStream 返回一个文件。 在我的测试用例中,该文件是一个简单的.PDF文件 我确信这个函数可以正常工作,因为我可以在ObjectiveC客户端应用程序上打开文件,在那里我使用了自己的http调用DataSnap方法no Delphi proxy。 流从ASIHttpRequest对象读取并保存为本地文件,然后加载并在标准pdf阅读器中正常显示。 我不知道AsitpRe
function TServerMethods.GetFile(filename): TStream
返回一个文件。
在我的测试用例中,该文件是一个简单的.PDF文件
我确信这个函数可以正常工作,因为我可以在ObjectiveC客户端应用程序上打开文件,在那里我使用了自己的http调用DataSnap方法no Delphi proxy。
流从ASIHttpRequest对象读取并保存为本地文件,然后加载并在标准pdf阅读器中正常显示。
我不知道AsitpRequest如何准确地管理返回的数据
但在JavaScript客户端,我使用标准
stream = ServerMethods().GetFile('test.pdf')
DataSnap代理本身提供的JavaScript函数,我不知道如何向用户显示.pdf数据
使用
将打开一个新的浏览器窗口,其中包含文本原始数据%PDF-1.5%–ãÓ1 0 obj一旦设置了ResponseContentType,服务器端代码将按预期工作。您可以通过直接从浏览器调用该方法来测试这一点。更改类名以匹配您正在使用的类名:
http://localhost:8080/datasnap/rest/TServerMethods1/GetFile/test.pdf
我确信有一种方法可以在浏览器端正确显示流,但我不确定这是什么。除非您对流做了一些特殊的处理,否则我建议您直接获取文档,或者使用web操作并避开浏览器。基本上是美赞臣的建议
我可以想出几个解决办法
1一个快速的方法是允许直接访问文档
在WebFileDispatcher中,添加WebFileExtension。选择.pdf,它将为您填写mime类型。假设您的pdf文档位于docs文件夹中,url可能如下所示:
http://localhost:8080/docs/test.pdf
2我可能会在web模块上添加一个操作。这有点牵扯,但也给了我更多的控制权
使用此url:
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;
是否无法将PDF文档流中的资源数据与web资源地址(例如)关联http://example.com/resources/mypdf 在DataSnap中?然后打开窗户http://example.com/resources/mypdf“应该有用。谢谢@mjn。创建服务器端文件资源可以是一个选项,我将尝试它。我也将尝试从JavaScript直接调用DataSnap REST方法,绕过代理方法。您正在创建什么类型的REST服务器?哪个巫师?DataSnap REST Server应用程序向导中有一个错误,它使覆盖ResponseContentType变得不可能。您好@AndersE.Andersen,我读了您的,我尝试了一下,但没有成功地完成完整的JavaScript设计。我使用了Delphi XE3,DataSnap Rest应用程序向导,用于调试目的。但现在,通过直接URL请求,浏览器最终会正确显示pdf。但是如果可能的话,我正在寻找一个纯JavaScript设计。好吧,那么听起来并不是这个bug导致了这个问题。您是否尝试过先调用document.openapplication/pdf,然后调用document.write..pdf数据。。最后是文件。结束?谢谢@Bruce,我确认这一切正常。这是一个有用的解决方法,但我真正的问题是,是否有可能像DataSnap framework提供的那样,在JSON响应中处理JSON调用返回的PDF流数据,只是为了显示它。在应用程序或桌面应用程序中,我们可以保存PDF流并将其显示给用户,我们可以在AJAX查询中获取数据并等待回调,我们可以在显示流之前处理流,等等。。在浏览器JavaScript web应用程序中是否有这样做的方法?听起来好像不是。我设法使您的第二个建议操作在我的Rest服务器中工作,但请求为空。有什么想法吗?
GetInvocationMetadata().ResponseContentType := 'application/pdf';
http://localhost:8080/datasnap/rest/TServerMethods1/GetFile/test.pdf
http://localhost:8080/docs/test.pdf
http://localhost:8080/getfile?filename=test.pdf
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;