2012-12-14 6 views

Antwort

17

Das Problem ist, dass Delphi REST-Server immer setzt den Inhaltstyp/html in Text. Dies verwirrt den Browser, wenn Sie andere Arten von Inhalten senden. Es ist ein Fehler, da die meisten Antworten json sind, was bedeutet, dass der sinnvollste Standard Inhaltstyp die Anwendung/json sein sollte.

Glücklicherweise gibt es eine Möglichkeit, den Inhaltstyp innerhalb der Servermethode zu überschreiben.

Sie müssen Data.DBXPlatform zur Verwendungsliste Ihrer Implementierung hinzufügen.

Diese Einheit enthält die Funktion GetInvocationMetadata, die Zugriff auf die Antwort gibt, die gerade erstellt wird. Sie gibt ein TDSInvocationMetadata Objekt zurück, das unter verschiedenen anderen nützlichen Eigenschaften die ResponseContentType Eigenschaft besitzt.

Durch das Festlegen dieser Eigenschaft wird der Content-Type-Header überschrieben, den die Methode in der HTTP-Antwort zurückgibt.

Das gegebene Beispiel wird:

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

Nun wird das Ergebnisbild korrekt im Browser angezeigt werden.

1

Ich habe dieses Problem auch beim Versuch gefunden, verschiedene Dateitypen (png, pdf, xlsx, docx, etc ...) vom DataSnap REST Server (Delphi XE3) auf einen JavaScript Webclient herunterzuladen. Einige Browser (z. B. Firefox) werden trotzdem die richtigen Maßnahmen ergreifen, aber nicht alle. Internet Explorer erkennt die richtige Aktion für die heruntergeladene Datei ohne richtigen Inhaltstyp nicht. Die @Anders-Lösung scheint zunächst für mich zu funktionieren, da ich mit PDF und Firefox gearbeitet habe. Aber wenn ich auf IE (und andere) und mit verschiedenen Erweiterungen getestet habe, wurden die Dateien nicht erkannt. Mit Firebug habe ich die Content-Type gesehen war immer "text/html" und nicht die zugeordnete eines mit

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

Die Abhilfe gefunden für mich arbeiten ist:

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; 

habe ich eine ähnliche Lösung Content-Disposition für die Zuordnung auch. Dies ist ein nützlicher Header-Schlüssel, um den Dateinamen in den Download- und Attachment/Inline-Modus zu setzen. diese mit dem Code ist:

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 in die Umsetzung Server-Methoden.

EDIT

Diese Problemumgehung in ISAPI DLL auf IIS funktioniert nicht mit Datenkomprimierung aktiviert! ohne Daten compressione (lokale debuggin IIS) die Antwort-Header ist:

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 

aber aktiviert mit der Produktion der Antwort IIS kommt mit:

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 und Content-Typ in DataSnap-Code zugewiesen sind nicht aufgetaucht.