【发布时间】:2014-10-18 07:35:07
【问题描述】:
我一直在使用 Synapse 库从 Internet 下载文件,但我最近将我的应用程序转换为使用 INDY,我错过了 Synapse 库中更好的功能之一,即能够轻松获取 Mime -在将文件保存到本地计算机之前从服务器下载的文件的类型。 INDY 有这个功能吗?如果有,我该如何访问它?
【问题讨论】:
标签: delphi mime-types indy
我一直在使用 Synapse 库从 Internet 下载文件,但我最近将我的应用程序转换为使用 INDY,我错过了 Synapse 库中更好的功能之一,即能够轻松获取 Mime -在将文件保存到本地计算机之前从服务器下载的文件的类型。 INDY 有这个功能吗?如果有,我该如何访问它?
【问题讨论】:
标签: delphi mime-types indy
您可以发出 HTTP HEAD 请求并检查 Content-Type 标头。在您实际GET 文件(下载)之前:
procedure TForm1.Button1Click(Sender: TObject);
var
Url: string;
Http: TIdHTTP;
begin
Url := 'http://yoursite.com/yourfile.png';
Http := TIdHTTP.Create(nil);
try
Http.Head(Url);
ShowMessage(Http.Response.ContentType); // "image/png"
finally
Http.Free;
end;
end;
您收到的ContentType 取决于网络服务器的实现,不保证在每台服务器上都相同。
另一个选项是实际GET 文件并将其内容保存到内存流,例如TMemoryStream(而不是本地文件)。 Indy 提供了一个重载:
Http.Get(Url, AStream);
然后检查Http.Response.ContentType,并将流保存到文件:AStream.SaveToFile。
不确定此处的相关性,但还要注意 Indy 也可以返回/猜测本地文件的 mime 类型(给定文件扩展名)。与GetMIMETypeFromFile(使用IdGlobalProtocols)。另见here。
【讨论】:
或者你可以构建你的函数
function GetMIMEType(sFile: TFileName): string;
var aMIMEMap: TIdMIMETable;
begin
aMIMEMap:= TIdMIMETable.Create(true);
try
result:= aMIMEMap.GetFileMIMEType(sFile);
finally
aMIMEMap.Free;
end;
end;
然后调用
procedure HTTPServerGet(aThr: TIdPeerThread; reqInf: TIdHTTPRequestInfo;
respInf: TIdHTTPResponseInfo);
var localDoc: string;
ByteSent: Cardinal;
begin
//RespInfo.ContentType:= 'text/HTML';
Writeln(Format('Command %s %s at %-10s received from %s:%d',[ReqInf.Command, ReqInf.Document,
DateTimeToStr(Now),aThr.Connection.socket.binding.PeerIP,
aThr.Connection.socket.binding.PeerPort]));
localDoc:= ExpandFilename(Exepath+'/web'+ReqInf.Document);
RespInf.ContentType:= GetMIMEType(LocalDoc);
if FileExists(localDoc) then begin
ByteSent:= HTTPServer.ServeFile(AThr, RespInf, LocalDoc);
Writeln(Format('Serving file %s (%d bytes/ %d bytes sent) to %s:%d at %s',
[LocalDoc,ByteSent,FileSizeByName(LocalDoc), aThr.Connection.Socket.Binding.PeerIP,
aThr.Connection.Socket.Binding.PeerPort, dateTimeToStr(now)]));
end else begin
RespInf.ResponseNo:= 404; //Not found RFC
RespInf.ContentText:=
'<html><head><title>Sorry WebBox Error</title></head><body><h1>' +
RespInf.ResponseText + '</h1></body></html>';
end;
end;
【讨论】:
GetMIMETypeFromFile(我有点后悔我这样做了)。您的代码是报告内容类型的 服务器 端实现。 OP 询问 HTTP 客户端。但另一方面,这显示了我在回答中写的 OP “您收到的 ContentType 取决于 Web 服务器的实现,并且不保证在每台服务器上都相同”:)