最近項目中遇到了這個問題,以前沒有怎么關注過,自己探究一番,查看以前寫的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指定的,默認的方式確實問題多多,還是指名道姓的好。