Reliably getting favicons in Chrome extensions, chrome://favicon?

后端 未结 4 1765
生来不讨喜
生来不讨喜 2020-12-23 10:15

I\'m using the chrome://favicon/ in my Google Chrome extension to get the favicon for RSS feeds. What I do is get the base path of linked page, and append it to

相关标签:
4条回答
  • 2020-12-23 10:29

    I've seen this problem as well and it's really obnoxious.

    From what I can tell, Chrome populates the chrome://favicon/ cache after you visit a URL (omitting the #hash part of the URL if any). It appears to usually populate this cache sometime after a page is completely loaded. If you try to access chrome://favicon/http://yoururl.com before the associated page is completely loaded you will often get back the default 'globe icon'. Subsequently refreshing the page you're displaying the icon(s) on will then fix them.

    So, if you can, possibly just refreshing the page you're displaying the icons on just prior to displaying it to the user may serve as a fix.

    In my use case, I am actually opening tabs which I want to obtain the favicons from. So far the most reliable approach I have found to obtain them looks roughly like this:

    chrome.webNavigation.onCompleted.addListener(onCompleted);
    
    function onCompleted(details)
    {
        if (details.frameId > 0)
        {
            // we don't care about activity occurring within a subframe of a tab
            return;
        }
    
        chrome.tabs.get(details.tabId, function(tab) {
            var url = tab.url ? tab.url.replace(/#.*$/, '') : ''; // drop #hash
            var favicon;
            var delay;
    
            if (tab.favIconUrl && tab.favIconUrl != '' 
                && tab.favIconUrl.indexOf('chrome://favicon/') == -1) {
                // favicon appears to be a normal url
                favicon = tab.favIconUrl;
                delay = 0;
            }
            else {
                // couldn't obtain favicon as a normal url, try chrome://favicon/url
                favicon = 'chrome://favicon/' + url;
                delay = 100; // larger values will probably be more reliable
            }
    
            setTimeout(function() {
                /// set favicon wherever it needs to be set here
                console.log('delay', delay, 'tabId', tab.id, 'favicon', favicon);
            }, delay);
        });
    }
    

    This approach returns the correct favicon about 95% of the time for new URLs, using delay=100. Increasing the delay if you can accept it will increase the reliability (I'm using 1500ms for my use case and it misses <1% of the time on new URLs; this reliability worsens when many tabs are being opened simultaneously). Obviously this is a pretty imprecise way of making it work but it is the best method I've figured out so far.

    Another possible approach is to instead pull favicons from http://www.google.com/s2/favicons?domain=somedomain.com. I don't like this approach very much as it requires accessing the external network, relies on a service that has no guarantee of being up, and is itself somewhat unreliable; I have seen it inconsistently return the "globe" icon for a www.domain.com URL yet return the proper icon for just domain.com.

    Hope this helps in some way.

    0 讨论(0)
  • 2020-12-23 10:29

    I inspected the website-icon in Chrome history page and found this simpler method. You can get the favicon url by --

    favIconURL = "chrome://favicon/size/16@1x/" + tab.url;
    

    Don't forget to add "permissions" and "content_security_policy" to Chrome. (https://stackoverflow.com/a/48304708/9586876)

    0 讨论(0)
  • In the latest version of Chrome, Version 78.0.3904.87 (Official Build) (64-bit)) when tested, adding just img-src chrome://favicon; as content_security_policy will still show 2 warnings:

    'content_security_policy': CSP directive 'script-src' must be specified (either explicitly, or implicitly via 'default-src') and must whitelist only secure resources.

    And:

    'content_security_policy': CSP directive 'object-src' must be specified (either explicitly, or implicitly via 'default-src') and must whitelist only secure resources.

    To get rid of them use:

    "permissions": ["chrome://favicon/"],
    "content_security_policy": "script-src 'self'; object-src 'self'; img-src chrome://favicon;"
    

    Now you can use chrome://favicon/http://example.com without getting any errors or warnings.

    0 讨论(0)
  • 2020-12-23 10:41

    In order to use chrome://favicon/some-site in extension. manifest.json need to be updated:

    "permissions": ["chrome://favicon/"],
    "content_security_policy": "img-src chrome://favicon;"
    

    Test on Version 63.0.3239.132 (Official Build) (64-bit)

    0 讨论(0)
提交回复
热议问题