2012-12-14 107 views

回答

17

的問題是,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; 

現在的結果圖像將被正確地顯示在瀏覽器。

1

我發現這個問題也試圖從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 

內容處置和內容類型沒有浮出水面。

相關問題