开发 favicon 项目的一些总结
项目介绍
favicon 项目是一个获取目标网站 favicon 的工具。起初创建这个项目的缘由是在“发现”版块展示链接的图标:
获取一个网站的 favicon,是根据以下流程来进行的:
使用方法
只需要在路径里填写目标域名、网站、页面地址就可以。
https://f.ydr.me/baidu.com
https://f.ydr.me/https://baidu.com
https://f.ydr.me/https://baidu.com/a/b/c/d.html
图标 | 地址 |
---|---|
https://f.ydr.me/baidu.com | |
https://f.ydr.me/https://baidu.com | |
https://f.ydr.me/https://baidu.com/a/b/c/d.html |
难点介绍
1、图标是不是一个图片
有的网站根域图标就是一个空白的文件,有不是一个图片,这里根据两个规则来判断:
- 这个文件的长度是不是为 0
- 这个文件的类型是不是图片
示例代码:
var imageType = require('image-type');
if (buffer.length === 0) {
return callback(new Error('图片容量为 0 的 favicon 地址: ' + url));
}
if (!mime) {
var type = null;
try {
type = imageType(buffer);
} catch (err) {
// ignore
}
if (type) {
mime = type.mime;
}
}
if (imageMimeRE.test(mime)) {
// 删除 mime 头里的 charset 标识
mime = mime.replace(imageSuffRE, '');
return callback(null, {
buffer: buffer,
mime: mime
});
}
2、图标是一个 base64
有的网站的图标是一个 base64,这就是需要特殊处理,将 base64 转换成 buffer。
// data:image/ico;base64,
var matches = base64.match(base64RE);
if (matches && matches.length === 2) {
return callback(null, {
buffer: Buffer.from(base64, 'base64'),
mime: matches[1]
});
}
3、页面源代码不规范
有的网站 rel
属性不写或者 type
属性不写,或者重复;有的网站的 favicon 还分成多个 size。
// 查找 link 标签,按顺序匹配 link,查找是否有 favicon 标记
// 精确匹配:rel="shortcut icon" type="image/x-icon"
var faviconMatch0 = null;
// 有 sizes 属性的
var faviconMatch1 = null;
// 模糊匹配:rel="icon" type="image/**"
var faviconMatch2 = null;
var faviconMatchList = [];
$('link').each(function (index, link) {
var rel = (link.attribs['rel'] || '').toLowerCase();
var type = (link.attribs['type'] || '').toLowerCase();
var href = (link.attribs['href'] || '');
var sizes = (link.attribs['sizes'] || '').toLowerCase();
// <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
if (relIconRE.test(rel) && typeIconRE.test(type) && href) {
if (sizes) {
faviconMatchList.push({
sizes: sizes,
href: href
});
} else {
faviconMatch0 = fixedURL(href, lastRequestedURL);
}
}
if (faviconMatch0) {
return false;
}
if ((relIconRE.test(rel) || typeIconRE.test(type)) && href) {
if (sizes) {
faviconMatchList.push({
sizes: sizes,
href: href
});
} else {
faviconMatch2 = fixedURL(href, lastRequestedURL);
}
}
});
var foundFaviconUrl = null;
if (faviconMatch0) {
foundFaviconUrl = faviconMatch0;
} else if (faviconMatchList.length) {
var minSize = 0;
array.each(faviconMatchList, function (index, matched) {
var size = number.parseInt(matched.sizes.match(/^(\d+)x/)[1], 0);
if (minSize === 0 || size < minSize) {
faviconMatch1 = matched;
minSize = size;
}
});
foundFaviconUrl = faviconMatch1.href;
}
if (!foundFaviconUrl) {
foundFaviconUrl = faviconMatch2;
}
if (foundFaviconUrl) {
return {url: foundFaviconUrl, middleUrlList: middleUrlList};
}
throw new Error('favicon link 标签不存在');
特殊网站
目前该 favicon 服务被部分人使用了,其中发现一类 特殊性质 的网站,着实让我无语。
对这些网站进行黑名单处理,直接返回 204,结果页面长这样了:
对于那些非法或者不健康网站,本服务将进行黑名单处理,绝不姑息。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 我看互联网技术的中(后)台架构
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论