6

Deplhi TWebBrowser を使用してフォームに「ニュース」ページを表示したいと考えています。ニュース ページは、当社の Web サイトに随時アップロードする単純な HTML ページであり、さまざまなツールから出力される場合があります。表示は問題ありませんが、最後に表示してから変更されたかどうかをアプリで知りたいので、理想的には、変更された日付/時刻またはサイズ/チェックサムのいずれかを取得したいと考えています。精度は重要ではありません。理想的には、メモ帳などの HTML ファイルの編集に「単純な」ツールが使用されたため、失敗する可能性のあるプロパティに依存しないでください。Web で確認すると、いくつかのドキュメントが変更された Java 呼び出しがありますが、どこから始めればよいか本当にわかりません。私は、Delphi の Winapi の多数の呼び出しに目を通しました。WinInet ユニットと、HTTP でファイルを取得して調べることができるようですが、それはハンマーでクルミを割るように思えます。また、明らかな何かが欠けていると思わせるファイルの日時機能も表示されません。Delphi XE5 を使用しています。どの方向を見ればいいですか?ご指摘ありがとうございます。

4

2 に答える 2

4

IndyTIdHTTPを使用してリクエストを送信し、/ヘッダーHEADを調べることができます。Last-ModifiedContent-Length

例えば:

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

これらのヘッダー パラメーターは Web サーバーの実装に依存し、サーバー上のファイル システムの日付/時刻を返さない場合があります (動的ページなど)。サーバーがこれらのパラメーターをまったく返さない場合があります。

たとえば、HTMLIIS の静的ページでは、必要なLast-Modifiedファイル システムの最終変更日時が返されます。

動的コンテンツ (例: php、asp、.NET など) の場合、Web サーバーを制御する場合はHTTP、サーバー側に独自のカスタム応答ヘッダーを追加して、ファイル システムの日時 (例: X-Last-Modified) または必要に応じて応答Last-Modifiedヘッダーを設定し、クライアント側でこのヘッダーを調べます。


HTTP コンテンツ全体を検査/ハッシュする必要がある場合は、GETメソッド を発行する必要があります。http.Get(URL)

于 2014-08-11T11:03:37.127 に答える
1

kobik、David、および TLama からの提案と指摘のおかげで、私は実際に大ハンマーが必要であることに気付き、最終的にこの解決策を思いつきました (そして、私はおそらく最初でも最後でもありません!)。ファイルの内容を読む必要があったのは、これが変更を検出するより良い方法だと思われたからです。以下のコードは、まれに TTimer から「CheckForWebNewsOnTimer」を呼び出し、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;
于 2014-08-12T08:23:16.080 に答える