當您在Delphi休息服務器中使用文件流對象返回圖像時,它不會在瀏覽器中顯示。這裏是一個返回的圖像的示例性方法:從Delphi REST服務器返回圖像並在瀏覽器中顯示它
function TServerClass.Image: TFileStream;
begin
Result := TFileStream.Create('pathtofile\image.png', fmOpenRead or fmShareDenyNone);
end;
當您在Delphi休息服務器中使用文件流對象返回圖像時,它不會在瀏覽器中顯示。這裏是一個返回的圖像的示例性方法:從Delphi REST服務器返回圖像並在瀏覽器中顯示它
function TServerClass.Image: TFileStream;
begin
Result := TFileStream.Create('pathtofile\image.png', fmOpenRead or fmShareDenyNone);
end;
的問題是,Delphi的REST服務器始終將內容類型設置爲text/html。當您發送其他類型的內容時,這會使瀏覽器感到困惑。這是一個錯誤,因爲大多數響應都是json,這意味着最明智的默認內容類型應該是application/json。
幸運的是,有一種方法可以覆蓋服務器方法中的內容類型。
您需要將Data.DBXPlatform添加到實現的使用列表中。
本機包含功能GetInvocationMetadata,它可以訪問正在構建的響應。它返回一個TDSInvocationMetadata對象,其中多個其他有用的屬性具有ResponseContentType屬性。
設置此屬性將覆蓋該方法在http響應中返回的Content-Type標頭。
給出的例子就變成:
function TServerClass.Image: TFileStream;
begin
Result := TFileStream.Create('pathtofile\image.png', fmOpenRead or fmShareDenyNone);
GetInvocationMetadata.ResponseContentType := 'image/png';
end;
現在的結果圖像將被正確地顯示在瀏覽器。
我發現這個問題也試圖從DataSnap REST服務器(Delphi XE3)下載不同的文件類型(png,pdf,xlsx,docx等)到JavaScript Web客戶端。 某些瀏覽器(例如FireFox)無論如何都會採取正確的行動,但不是全部。如果沒有正確的內容類型,Internet Explorer無法識別下載文件的正確操作。 @Anders解決方案最初似乎適用於我,因爲我正在使用PDF和Firefox。 但是,當我測試了IE(和其他)和不同的擴展名,文件不識別。使用Firebug我見過的內容類型總是「text/html的」,而不是分配一個使用
GetInvocationMetadata.ResponseContentType := '...my assigned content type ...';
解決辦法找到工作對我來說是:
在ServerMethodsUnit
var
ContentTypeHeaderToUse: string; // Global variable
TServerMethods1.GetFile(params: JSON):TStream;
begin
.... processing ....
ContentTypeHeaderToUse := '...' (assign correct content type).
end;
在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;
我使用了類似的解決方案用於分配內容處置太。這是一個有用的標題鍵,用於將文件名設置爲下載和附件/內聯模式。 有了這一個代碼是:
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;
分配ContentDispositionHeaderToUse到服務器的方法實現。
編輯
此變通辦法不ISAPI DLL在IIS上啓用數據壓縮工作! 由於沒有數據compressione(本地debuggin IIS)響應標頭是:
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
但啓用生產IIS響應隨附:在的DataSnap代碼分配
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
內容處置和內容類型沒有浮出水面。