项目介绍

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,结果页面长这样了:

粘贴图片

对于那些非法或者不健康网站,本服务将进行黑名单处理,绝不姑息。

0 条评论
作者
状态
  • 发布于 ,1 次更新
  • 最后更新于
  • 被浏览 215 次
  • 被评论 0 次
  • 隶属于 文章 版块
  • 归纳于 轻松娱乐 分类
  • 收录于 轻松愉快 专辑
标签
二维码
目录