Return the image from the Delphi REST server and show it in the browser.

When you return an image using a file stream object on a Delphi leisure server, it will not be displayed in the browser. Here is an example of a method that returns an image:

function TServerClass.Image: TFileStream; begin Result := TFileStream.Create('pathtofile\image.png', fmOpenRead or fmShareDenyNone); end; 
+7
source share
2 answers

The problem is that the Delphi REST server always sets the content type to text / html. This confuses the browser when sending other types of content. This is a mistake, since most of the answers are json, which means that the most reasonable default content type should be application / json.

Fortunately, there is a way to override the content type from the server method.

You need to add Data.DBXPlatform to the use list of your implementation.

This block contains the GetInvocationMetadata function, which gives access to the response that is created. It returns a TDSInvocationMetadata object, which, among other useful varius properties, has a ResponseContentType property.

Setting this property overrides the Content-Type header, which the method returns in the http response.

The given example:

 function TServerClass.Image: TFileStream; begin Result := TFileStream.Create('pathtofile\image.png', fmOpenRead or fmShareDenyNone); GetInvocationMetadata.ResponseContentType := 'image/png'; end; 

Now the image of the result will be displayed correctly in the browser.

+17
source

I also found this problem while trying to upload various file types (png, pdf, xlsx, docx, etc.) from the DataSnap REST server (Delphi XE3) to the JavaScript web client. Some browsers (FireFox) will take the right action anyway, but not all. Internet Explorer does not recognize the correct action for the downloaded file without the correct content type. @Anders initially worked for me because I worked with PDF and Firefox. But when I tested IE (and others) and with different extensions, files that were not recognized. Using FireBug, I saw that Content-Type was always "text / html" and not assigned using

 GetInvocationMetadata.ResponseContentType := '...my assigned content type ...'; 

Workaround found for me:

In ServerMethodsUnit

 var ContentTypeHeaderToUse: string; // Global variable TServerMethods1.GetFile(params: JSON):TStream; begin .... processing .... ContentTypeHeaderToUse := '...' (assign correct content type). end; 

In WebModuleUnit

 procedure TWebModule1.WebModuleAfterDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin if ContentTypeHeaderToUse<>'' then begin Response.ContentType := ContentTypeHeaderToUse; ContentTypeHeaderToUse := ''; // Reset global variable end; end; 

I used a similar solution to assign Content-Disposition. This is a useful header to specify the file name for download and attachment / inline mode. With this code:

 procedure TWebModule1.WebModuleAfterDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin if ContentDispositionHeaderToUse<>'' then begin Response.SetCustomHeader('content-disposition',ContentDispositionHeaderToUse); ContentDispositionHeaderToUse := ''; end; if ContentTypeHeaderToUse<>'' then begin Response.ContentType := ContentTypeHeaderToUse; ContentTypeHeaderToUse := ''; end; end; 

Assign ContentDispositionHeaderToUse to the implementation of server methods.

EDIT

This workaround does not work in ISAPI DLLs in IIS with data compression enabled! No data compression (local debuggin IIS) response header:

 Connection close Content-Disposition inline; filename="Privacy-0.rtf.pdf" Content-Length 150205 Content-Type application/pdf; charset=ISO-8859-1 Pragma dssession=28177.371935.39223,dssessionexpires=1200000 

but with IIS enabled, the answer comes with:

 Content-Encoding gzip Content-Length 11663 Content-Type text/html Date Thu, 11 Sep 2014 21:56:43 GMT Pragma dssession=682384.52215.879906,dssessionexpires=1200000 Server Microsoft-IIS/7.5 Vary Accept-Encoding X-Powered-By ASP.NET 

The content-disposition and content type assigned in the DataSnap code are not displayed.

+1
source

All Articles