Java springboot favicon.ico 图标不显示探究
最近项目中遇到了这个问题,以前没有怎么关注过,自己探究一番,查看以前写的demo,竟然有的显示有的不显示,再查看以前的项目,老项目都没有问题,何故,深挖。
首先自然是百度,看到的说法都是两种,
方案一是把ico命名为favicon.ico,放到static下,自动显示。
方案二是spring.mvc.favicon.enabled=false,然后
在html文件中添加下面的
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
一测试无效,二可以,但是有问题,对于没有引用母版页的用起来太费劲。记得以前用iis的时候只要把ico命名为favicon.ico,放到根目录即可,所以说这个请求应该是浏览器主动发的,不应该页面引用,只能继续探究。
百度+查看springboot源码,找到WebMvcAutoConfiguration中有对favicon的处理,明白了上边方案一放到static下为什么自动显示,会自动匹配默认的四个静态资源路径
classpath:/META-INF/resources/ classpath:/resources/ classpath:/static/ classpath:/public/
外加一个"/"根路径
locations.add(new ClassPathResource("/"));
所以说放到这些目录下性质都是一样的
但是并没有解决问题,继续研究源码,无解。
回过头来思考,favicon.ico的机制问题,想到默认情况下view渲染时并没有渲染到ico,而是浏览器独自发起请求的,那么应该不是代码的问题,但是肯定也不是浏览器的问题,那为什么浏览器有时候请求,有时候不请求呢,首先想到缓存,但是正常的异步请求就算缓存也会正常请求,只是提示来自缓存,一直以为ico也应该是这样,而且浏览器也勾选了禁用缓存。查资料,结果看到一个说法,谷歌有就不会再请求,而火狐是大约2分钟请求一次,可以通过清除缓存或者ctrl+F5强制刷新请求,然后ctrl+F5测试,果然谷歌重新请求了favicon.ico,报404,查看路径,http://localhost/favicon.ico,到此瞬间恍悟,还是机制的问题,浏览器默认请求http://域名+favicon.ico,但是项目经常会配上项目名,也就是实际路径时http://域名+项目名+favicon.ico,路径错误,自然请求不到,由于谷歌的缓存机制,请求一次没请求到,后边不请求了,自然就没有了。
解决方案:
由于这是浏览器的策略问题,所以没有直接的解决方案,
方案一:不配项目名,http://域名(或者IP+端口)/favicon.ico能访问到图片,就没有问题
方案二:页面明确指定ico
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
但是这样比较费劲,所有页面都要加,折中方案就是用母版页,统一添加,已有项目的话改动也比较大,
折中方案二:通过拦截器,在页面渲染完成后追加一段js,
可以继承HandlerInterceptor接口,重写afterCompletion方法,添加以下代码通过js写入
String link = "<script>" + "var link = document.createElement('link');" + "link.type = 'image/x-icon';" + "link.rel = 'shortcut icon';" + "link.href = '/nascan/images/favicon.ico';" + "document.getElementsByTagName('head')[0].appendChild(link);" + "</script>"; response.getWriter().append(link);
注:有空继续研究,看有没有其他方法,看了一些网站,全都是通过link指定的,默认的方式确实问题多多,还是指名道姓的好。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步