I've found this problem too trying to download different file types (png, pdf, xlsx, docx, etc...) from DataSnap REST server (Delphi XE3) to a JavaScript web client.
Some browsers (es.: FireFox) will take correct action anyway, but not all. Internet Explorer doesn't recognize the proper action for the downloaded file without correct content-type.
The @Anders solution initially seems to work for me because I was working with PDF and Firefox.
But when I've tested on IE (and others) and with different extensions, the files where not recognised. Using FireBug I've seen that Content-Type was always "text/html" and not the assigned one using
GetInvocationMetadata.ResponseContentType := '...my assigned content type ...';
The workaround found working for me is:
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 for assigning Content-Disposition too. This is a useful header key in order to set file name to download and attachment/inline mode.
With this one the code is:
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 into the server methods implementation.
EDIT
This workaround doesn't work in ISAPI DLL on IIS with data compression enabled!
With no data compressione (local debuggin IIS) the response header is:
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 production enabled IIS the response 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
Content-disposition and content-type assigned in DataSnap code are not surfaced.