2012-12-14 24 views
7

Khi bạn trả lại hình ảnh bằng cách sử dụng đối tượng luồng tệp trong máy chủ phần còn lại Delphi, nó sẽ không hiển thị trong trình duyệt. Dưới đây là một phương pháp ví dụ trả về hình ảnh:Trả lại hình ảnh từ máy chủ REST Delphi và hiển thị nó trong trình duyệt

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

Trả lời

17

Vấn đề là máy chủ Delphi REST luôn đặt loại nội dung thành văn bản/html. Điều này gây nhầm lẫn cho trình duyệt khi bạn gửi các loại nội dung khác. Nó là một lỗi, vì hầu hết các câu trả lời là json, có nghĩa là loại nội dung mặc định hợp lý nhất nên là application/json.

May mắn thay có cách ghi đè loại nội dung từ bên trong phương thức máy chủ.

Bạn cần thêm dữ liệu.DBXPlatform vào danh sách sử dụng triển khai của bạn.

Đơn vị này chứa hàm GetInvocationMetadata, cho phép truy cập vào phản hồi đang được xây dựng. Nó trả về một đối tượng TDSInvocationMetadata trong số các thuộc tính hữu ích khác của varius có thuộc tính ResponseContentType.

Đặt thuộc tính này ghi đè tiêu đề Loại nội dung mà phương thức trả về trong phản hồi http.

Ví dụ cho trở thành:

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

Bây giờ hình ảnh kết quả sẽ được hiển thị đúng trong trình duyệt.

1

Tôi đã tìm thấy vấn đề này quá cố gắng tải xuống các loại tệp khác nhau (png, pdf, xlsx, docx, v.v ...) từ máy chủ REST DataSnap (Delphi XE3) thành ứng dụng web JavaScript. Một số trình duyệt (ví dụ: FireFox) sẽ thực hiện hành động đúng, nhưng không phải tất cả. Internet Explorer không nhận ra hành động thích hợp cho tệp được tải xuống mà không có loại nội dung chính xác. Giải pháp @Anders ban đầu có vẻ phù hợp với tôi vì tôi đã làm việc với PDF và Firefox. Nhưng khi tôi đã thử nghiệm trên IE (và những người khác) và với các phần mở rộng khác nhau, các tập tin mà không được công nhận. Sử dụng Firebug I have seen that Content-Type luôn "text/html" và không phải là một giao sử dụng

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

Cách giải quyết tìm thấy làm việc đối với tôi là:

Trong ServerMethodsUnit

var 
    ContentTypeHeaderToUse: string; // Global variable 

TServerMethods1.GetFile(params: JSON):TStream; 
begin 
    .... processing .... 
    ContentTypeHeaderToUse := '...' (assign correct content type). 
end; 

Trong 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; 

Tôi đã sử dụng giải pháp tương tự để gán Nội dung Bố trí quá. Đây là khóa tiêu đề hữu ích để đặt tên tệp để tải xuống và tệp đính kèm/chế độ nội tuyến. Với mã này là:

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; 

Gán ContentDispositionHeaderĐể sử dụng phương thức triển khai máy chủ.

EDIT

workaround này không hoạt động trong ISAPI DLL trên IIS với kích hoạt nén dữ liệu! Với không compressione dữ liệu (địa phương debuggin IIS) tiêu đề phản ứng là:

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 

nhưng với sản xuất được kích hoạt IIS phản ứng đi kèm với:

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 và loại nội dung được phân công trong mã DataSnap không nổi lên.

Các vấn đề liên quan