我想要显示一条新闻'使用Deplhi TWebBrowser的表单页面。新闻页面是一个简单的HTML页面,我们不时上传到我们的网站,可能会从各种工具输出。显示很好但我想在我的应用程序中知道自从我上次显示它以来它是否已经改变,所以理想情况下我想要获得其修改日期/时间或其大小/校验和。精确度并不重要,理想情况下不应该依赖可能失败的属性,因为简单'工具用于编辑HTML文件,如NotePad。检查网上有几个文件修改过的java调用,但我真的不知道从哪里开始。我查看了Delphi的Winapi.WinInet单元中的大量调用,我看到我可以通过HTTP获取文件来检查它,但这似乎是用大锤敲碎核桃。我也看不到任何文件日期时间功能,这让我觉得我错过了一些明显的东西。我使用的是Delphi XE5。我应该朝哪个方向看?谢谢你的任何指示。
答案 0 :(得分:4)
您可以使用Indy TIdHTTP
发送HEAD
请求并检查Last-Modified
/ Content-Length
标题。
e.g:
procedure TForm1.Button1Click(Sender: TObject);
var
Url: string;
Http: TIdHTTP;
LastModified: TDateTime;
ContentLength: Integer;
begin
Url := 'http://yoursite.com/newspage.html';
Http := TIdHTTP.Create(nil);
try
Http.Head(Url);
LastModified := Http.Response.LastModified;
ContentLength := Http.Response.ContentLength;
ShowMessage(Format('Last-Modified: %s ; Content-Length: %d', [DateTimeToStr(LastModified), ContentLength]));
finally
Http.Free;
end;
end;
触发TWebBrowser.DocumentComplete
事件后,发出HEAD
个请求并存储LastModified
和ContentLength
个变量。
然后定期发出HEAD
次请求以测试更改(例如,通过TTimer
)。
这些Header参数取决于Web服务器实现,并且可能不会在服务器上返回文件系统日期时间(例如,动态页面)。您的服务器可能不会回复这些参数。
例如,对于IIS上的静态HTML
页面,Last-Modified
将返回文件系统上次修改日期时间,这是您想要的。
对于动态内容(例如php,asp,.NET等..),如果你控制web服务器,你也可以在服务器端添加你自己的自定义HTTP
响应头来指示文件系统日期时间(例如X-Last-Modified
)或根据需要设置响应Last-Modified
标题,并在客户端检查此标题。
如果您需要检查/哈希整个HTTP内容,则需要发出GET
方法:http.Get(URL)
答案 1 :(得分:1)
感谢kobik,David和TLama提出的各种建议和指示,我意识到我确实需要一把大锤,我终于想出了这个解决方案(我可能不是第一个,也可能是最后一个) !)。我不得不阅读文件内容,因为这似乎是检测更改的更好方法。下面的代码调用" CheckForWebNewsOnTimer"从一个不常见的TTimer并使用Indy读取新闻页面,制作其内容的MD5哈希并将其与存储在注册表中的先前哈希进行比较。如果内容发生变化,或者过了120天,页面会弹出。代码有皱纹,例如对页面上链接图像的更改可能不会触发更改但是嘿,它唯一的新闻和文本几乎总是会发生变化。
function StreamToMD5HashHex( AStream : TStream ) : string;
// Creates an MD5 hash hex of this stream
var
idmd5 : TIdHashMessageDigest5;
begin
idmd5 := TIdHashMessageDigest5.Create;
try
result := idmd5.HashStreamAsHex( AStream );
finally
idmd5.Free;
end;
end;
function HTTPToMD5HashHex( const AURL : string ) : string;
var
HTTP : TidHTTP;
ST : TMemoryStream;
begin
HTTP := TidHTTP.Create( nil );
try
ST := TMemoryStream.Create;
try
HTTP.Get( AURL, ST );
Result := StreamToMD5HashHex( ST );
finally
ST.Free;
end;
finally
HTTP.Free;
end;
end;
function ShouldShowNews( const ANewHash : string; AShowAfterDays : integer ) : boolean;
const
Section = 'NewsPrompt';
IDHash = 'LastHash';
IDLastDayNum = 'LastDayNum';
var
sLastHash : string;
iLastPromptDay : integer;
begin
// Check hash
sLastHash := ReadRegKeyUserStr( Section, IDHash, '' );
Result := not SameText( sLastHash, ANewHash );
if not Result then
begin
// Check elapsed days
iLastPromptDay := ReadRegKeyUserInt( Section, IDLastDayNum, 0 );
Result := Round( Now ) - iLastPromptDay > AShowAfterDays;
end;
if Result then
begin
// Save params for checking next time.
WriteRegKeyUserStr( Section, IDHash, ANewHash );
WriteRegKeyUserInt( Section, IDLastDayNum, Round(Now) );
end;
end;
procedure CheckForWebNewsOnTimer;
var
sHashHex, S : string;
begin
try
S := GetNewsURL; // < my news address
sHashHex := HTTPToMD5HashHex( S );
If ShouldShowNews( sHashHex, 120 {days default} ) then
begin
WebBrowserDlg( S );
end;
except
// .. ignore or save as info
end;
end;