Johnny with dotnet

如何判断一个url是否更新了

最近在做这个调研,基本上找到了3种方法:

  1. 使用HttpWebRequest和HttpWebResponse的Headers。

Header中包含两个和Modify相关的key,

    一个是eTag(http://www.baike.com/wiki/Etag),这个是entity id。

     另一个是Lasted-Modified。最后修改时间。

使用这两个header来判断的时候,最好是同时使用,且Etag优先。

  这样做的一个好处是: 如果这个网页只是更新了last-modify的时候,而没有改变内容的情况下,也会返回304.

//响应第一次,获得这两个值:
   HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
   HttpWebResponse res = req.GetResonse() as HttpWebResponse;

   stringeTag= res.Headers[HttpWebResponse.ETag];
   string lastModified = res.Headers[HttpWebResponseHeader.LastModified]

//第二次响应,将上面两个值写入WebRequest的Header传入。
  HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
  req.Methid="GET";
  req.Headers[HttpRequestHeader.IfNoneMatch] = eTag;
  req.IfModifiedSinse = ifModifiedSince;
   HttpWebResponse res = req.GetResonse() as HttpWebResponse;
   //判断response的statusCode
   if(res.StatusCode == HttpStatusCode.NotModified) {}
(注意:)这种方式对于静态页面适用,但是对于动态页面就不适应了。因为动态页面的LastModified时间是服务器发送Response的时间,并非网页的最后更新时间。而Etag通常为空值。
2. 使用给Response的Stream使用MD5(或者SHA1)签名: 最推荐的方法。
对第一次和第二次响应的流分别进行MD5签名,然后进行比较。如果不同则,内容有变。
Md5算法对于文本流的签名很快,M级的数据可在毫秒内完成。
private static string HashData(System.IO.Stream stream, string algName)
        {
            stream.Seek(0, System.IO.SeekOrigin.Begin);
            System.Security.Cryptography.HashAlgorithm algorithm;

            if (algName == null)
            {
                throw new ArgumentNullException("algName 不能为 null");
            } 
            if (string.Compare(algName, "sha1",true) == 0)
            { 
                algorithm = System.Security.Cryptography.SHA1.Create(); 
            }
            else
            {
                if (string.Compare(algName, "md5", true) != 0)
                {
                    throw new Exception("algName 只能使用 sha1 或 md5");
                } 
                algorithm = System.Security.Cryptography.MD5.Create();
            }
          byte[] resultByteAr= algorithm.ComputeHash(stream);
         return BitConverter.ToString(resultByteAr).Replace("-","");
        }

3. 还有一种,但是这种的准确率不很精确: 每次下载一段长度的response的byte,然后呢比较。
这里面主要是使用Range Header来get一段byte[]内容存储,然后第二次的时候,get相同位置的byte[],进行比较。
 

posted on 2012-12-07 11:04  JohnnyNet  阅读(1830)  评论(1编辑  收藏  举报

导航