如何判断一个url是否更新了
最近在做这个调研,基本上找到了3种方法:
- 使用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) 编辑 收藏 举报