2012-12-14 5 views

risposta

17

Il problema è che server di Delphi REST imposta sempre il tipo di contenuto a text/html. Ciò confonde il browser quando invii altri tipi di contenuti. È un bug, dal momento che la maggior parte delle risposte sono json, il che significa che il tipo di contenuto predefinito più ragionevole dovrebbe essere application/json.

Fortunatamente esiste un modo per sovrascrivere il tipo di contenuto all'interno del metodo server.

È necessario aggiungere Data.DBXPlatform all'elenco degli usi della propria implementazione.

Questa unità contiene la funzione GetInvocationMetadata, che consente di accedere alla risposta che si sta creando. Restituisce un oggetto TDSInvocationMetadata che tra le altre proprietà utili ha la proprietà ResponseContentType.

L'impostazione di questa proprietà sostituisce l'intestazione Content-Type che il metodo restituisce nella risposta http.

L'esempio dato diventa:

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

Ora l'immagine risultato viene visualizzato correttamente nel browser.

1

Ho riscontrato questo problema anche nel tentativo di scaricare diversi tipi di file (png, pdf, xlsx, docx, ecc.) Dal server REST di DataSnap (Delphi XE3) a un client Web JavaScript. Alcuni browser (es .: FireFox) prenderanno comunque le misure corrette, ma non tutte. Internet Explorer non riconosce l'azione corretta per il file scaricato senza il tipo di contenuto corretto. La soluzione di @Anders inizialmente sembra funzionare per me perché stavo lavorando con PDF e Firefox. Ma quando ho provato su IE (e altri) e con diverse estensioni, i file non sono riconosciuti. Usando Firebug ho visto che Content-Type è sempre stato "text/html" e non quello assegnato utilizzando

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

La soluzione trovata a lavorare per 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; 

ho usato una soluzione simile per l'assegnazione di Content-Disposition pure. Questa è una chiave di intestazione utile per impostare il nome del file da scaricare e l'allegato/modalità inline. Con questo codice è:

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; 

Assegna ContentDispositionHeaderToUse nell'attuazione metodi del server.

EDIT

Questa soluzione non funziona in ISAPI DLL su IIS con la compressione dei dati abilitata! Senza compression dati (locale IIS debuggin) l'intestazione della risposta è:

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 

ma con la produzione abilitato IIS la risposta viene fornito con:

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 e Content-Type assegnato nel codice DataSnap non sono emersi

Problemi correlati