开发 favicon 项目的一些总结

发布于 2021-12-18 18:33:51 字数 4594 浏览 1208 评论 0

项目介绍

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、图标是不是一个图片

有的网站根域图标就是一个空白的文件,有不是一个图片,这里根据两个规则来判断:

  1. 这个文件的长度是不是为 0
  2. 这个文件的类型是不是图片

示例代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
569 人气
更多

推荐作者

lioqio

文章 0 评论 0

Single

文章 0 评论 0

禾厶谷欠

文章 0 评论 0

alipaysp_2zg8elfGgC

文章 0 评论 0

qq_N6d4X7

文章 0 评论 0

放低过去

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文