自从我上次显示Delphi TWebBrowser网页后,检测Delphi TWebBrowser网页的最佳方法是什么?

时间:2014-08-11 09:38:15

标签: delphi twebbrowser tdatetime

我想要显示一条新闻'使用Deplhi TWebBrowser的表单页面。新闻页面是一个简单的HTML页面,我们不时上传到我们的网站,可能会从各种工具输出。显示很好但我想在我的应用程序中知道自从我上次显示它以来它是否已经改变,所以理想情况下我想要获得其修改日期/时间或其大小/校验和。精确度并不重要,理想情况下不应该依赖可能失败的属性,因为简单'工具用于编辑HTML文件,如NotePad。检查网上有几个文件修改过的java调用,但我真的不知道从哪里开始。我查看了Delphi的Winapi.WinInet单元中的大量调用,我看到我可以通过HTTP获取文件来检查它,但这似乎是用大锤敲碎核桃。我也看不到任何文件日期时间功能,这让我觉得我错过了一些明显的东西。我使用的是Delphi XE5。我应该朝哪个方向看?谢谢你的任何指示。

2 个答案:

答案 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个请求并存储LastModifiedContentLength个变量。 然后定期发出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;