Firefox 動態(tài)修改 favicon 不顯示問題

1 問題

項目中需要動態(tài)改變頁面的 favicon廊移,icon 文件存儲在阿里云(OSS)上材蛛。改變 favicon 的方式是通過獲取 link 元素太伊,把 icon 的 url 賦值給其 href妻怎。在 chrome 上測試可以正確顯示刁赖,但是在 firefox 上卻沒有顯示圖標(biāo)搁痛。

2 分析

動態(tài)改變 favicon 以前我也沒有做過,秉承不放過一個可能的 debug 策略宇弛,首先懷疑 firefox 不支持動態(tài)修改 link[rel=icon]鸡典。于是打開 fiddler 查看在動態(tài)賦值圖標(biāo) url 后有沒有圖片請求發(fā)出(firefox自帶的開發(fā)者工具中沒有顯示 link[rel=icon] 的請求)。在 fiddler 中發(fā)現(xiàn) firefox 是發(fā)送了請求的枪芒,那么接下來就看下返回了彻况。此時發(fā)現(xiàn)阿里云返回的是403,估計是請求頭缺少了什么東西導(dǎo)致請求被阿里云屏蔽了舅踪。查看圖片的請求頭發(fā)現(xiàn)缺少 Referer纽甘,估計就是這個影響了。我重新打開 chrome 看了下圖片的請求是有 Referer 的抽碌,那么基本上可以確定這是 firefox 的一個 bug悍赢。最終我去到阿里云的管理界面看了下防盜鏈的設(shè)置界面,里面選擇的是 Referer 不能為空货徙,這下證實了我的猜測:由于 firefox 的加載 favicon 的時候左权,請求頭缺少了 Referer,被阿里云防盜鏈了痴颊。

3 解決方案

解決方案其實是在 google 的時候發(fā)現(xiàn)的赏迟,link[rel=icon] 的 href 不但可以寫 url,還可以寫圖片的 base64 編碼蠢棱,和 img 標(biāo)簽一樣锌杀。那么我是否可以用 img 標(biāo)簽加載這個圖標(biāo)然后轉(zhuǎn)成 base64 編碼再賦值給 link[rel=icon] 呢?說干就干裳扯,依稀記得轉(zhuǎn) base64 編碼可以使用 canvas.toDataURL 這個 API 來轉(zhuǎn)抛丽,查了下瀏覽器支持情況,幸好項目要求支持的瀏覽器都支持饰豺。代碼如下:


let ImageContentTypeMap:any = {
  jpg: 'image/jpeg',
  jpeg: 'image/jpeg',
  png: 'image/png',
  ico: 'image/x-icon',
  gif: 'image/gif'
}

function parseSuffix( url:string ):string {
  if ( url ) {
    let lastDotIndex = url.lastIndexOf( '.' );
    if ( lastDotIndex >= 0 ) {
      return url.substr( lastDotIndex + 1 ).toLowerCase();
    } else {
      return '';
    }
  } else {
    return '';
  }
}
/*
請忽略為啥要用 promise亿鲜,只是 copy 出來懶得改了
*/
function imageToBase64( url, width, height ) {
  return new Promise( function( resolve, reject ) {
      let img = new Image; 
      img.crossOrigin = 'Anonymous'; 
      img.onload = function() {
          var canvas = document.createElement( 'canvas' );
          canvas.width = width;
          canvas.height = height;
          var ctx = canvas.getContext( '2d' );
          ctx.drawImage( img, 0, 0 );
          let imgSuffix = parseSuffix( url );
          if ( imgSuffix ) {
            let contentType = ImageContentTypeMap[imgSuffix];
            if ( contentType ) {
              resolve( canvas.toDataURL( contentType ) );
            } else {
              reject( new Error('Can not parse contentType of favicon') )
            }
          } else {
            reject( new Error('Can not parse suffix of favicon file') )
          }
      }
      // TODO: 當(dāng)圖片加載失敗的情況
      img.src = url;
  } )
}

let iconLink = document.getElementById('iconLink');
imageToBase64( '....../xxx.ico', 16, 16 ).then( imgStr=>{
    iconLink.href = imgStr;
} ).catch( e=>{
    console.error( 'Parse favicon: ', e.stack );
} )

測試結(jié)果是 icon 圖片是顯示出來了,但是只顯示了部分圖片(囧)冤吨。那...應(yīng)該可能是圖標(biāo)有問題蒿柳?遂找了另外一個 png 的圖標(biāo)試試了,測試通過漩蟆。難道是 firefox 中使用 img 加載 ico 文件有問題垒探?只能上 google 大法了,經(jīng)過了一番搜索和測試基本能確定下來怠李,firefox 顯示 ico 文件是沒有問題的圾叼,但是 canvas.toDataURL 這個 API 在不同的瀏覽器中支持的圖片格式有偏差蛤克,而且格式類型支持的都有限。所以我們最初用的 ico 文件通過 canvas.toDataURL encode 之后的編碼不是完全正確的夷蚊。此時我想到兩個解決方案:

  1. favicon 改換成 png 圖片构挤。
  2. 后臺直接給出的不是 icon 的 url,而是 base64 的編碼惕鼓。(用 ico 文件正確的 base64 編碼做過測試筋现,firefox 能夠正確顯示圖標(biāo))

至此 firefox 不支持動態(tài)修改 favicon 的問題算解決了。

延伸資料

Favicon 歷史 - https://en.wikipedia.org/wiki/Favicon
各瀏覽器支持顯示的圖片格式 - https://en.wikipedia.org/wiki/Comparison_of_web_browsers#Image_format_support

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末箱歧,一起剝皮案震驚了整個濱河市矾飞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呀邢,老刑警劉巖洒沦,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驼鹅,居然都是意外死亡微谓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門输钩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人仲智,你說我怎么就攤上這事买乃。” “怎么了钓辆?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵剪验,是天一觀的道長。 經(jīng)常有香客問我前联,道長功戚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任似嗤,我火速辦了婚禮啸臀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烁落。我一直安慰自己乘粒,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布伤塌。 她就那樣靜靜地躺著灯萍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪每聪。 梳的紋絲不亂的頭發(fā)上旦棉,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天齿风,我揣著相機(jī)與錄音,去河邊找鬼绑洛。 笑死救斑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诊笤。 我是一名探鬼主播系谐,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼讨跟!你這毒婦竟也來了纪他?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤晾匠,失蹤者是張志新(化名)和其女友劉穎茶袒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凉馆,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡薪寓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澜共。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片向叉。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嗦董,靈堂內(nèi)的尸體忽然破棺而出母谎,到底是詐尸還是另有隱情,我是刑警寧澤京革,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布奇唤,位于F島的核電站,受9級特大地震影響匹摇,放射性物質(zhì)發(fā)生泄漏咬扇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一廊勃、第九天 我趴在偏房一處隱蔽的房頂上張望懈贺。 院中可真熱鬧,春花似錦供搀、人聲如沸隅居。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胎源。三九已至,卻和暖如春屿脐,著一層夾襖步出監(jiān)牢的瞬間涕蚤,已是汗流浹背宪卿。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留万栅,地道東北人佑钾。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像烦粒,于是被迫代替她去往敵國和親休溶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容