扣丁書屋

漫步于第三方線上代碼中——記一次排查內嵌谷歌地圖在 ios 上黑屏問題

某日,qa 反饋說『ios 上的谷歌地圖顯示不出來,黑屏啦~』,我一邊心想本周已經是第 x 個內嵌鏈接的 bug 了,這些第三方鏈接還能不能好了一邊很不追求極致的嘟囔著為什么第三方鏈接的 bug 也要我看,一邊苦逼的打開 ipad 模擬器,投入到痛苦的 safari debug 工作中。

safari, 新時代的 ie

問題表現如下:

排查思路

一開始的我沒有很清晰的解決思路,想著會不會是谷歌地圖對 iPad 兼容有問題,因此看了下 iPad 的 safari 瀏覽器是否也有問題,發現并沒有。

然后我想會不會是 ios 嵌入文檔時,對谷歌地圖的一些資源進行了攔截,導致其直接黑屏了,因此我對比了一下 network 訪問,如下:

? 不正常的情況:

?? 正常的情況:

可以看到正常的時候確實比不正常的時候訪問多了很多資源,但是其中并沒有什么訪問失敗的部分,所以攔截的猜想也是錯的。

后來,我對比了下兩邊的 html 結構,發現正常的時候,mapDiv 這個元素下會有內容,而不正常的時候是空的,如下:

可見,正常情況下谷歌地圖會往這個 div 里插入地圖的內容,這個問題的根源在于,谷歌地圖不知道出于什么原因沒有往 mapDiv 里插入內容。

到這里為止應該是很容易想到的部分,那么,我們怎么才能知道是哪個地方導致的呢?

debug 谷歌地圖

找到 appendChild 的地方

要往一個 div 里插入內容,最容易想到的方法是什么?答案顯然易見,就是 appendChild(或者 append),所以我在控制臺里改造了一下 Element 的原型,使每一次 appendChild 時,我都能看到日志,如下:

const appendChild = Element.prototype.appendChild;
// 這個地方能否使用箭頭函數呢?^-^
Element.prototype.appendChild = function(...args) {
  console.log('append', this.className);
  if (this.id === 'mapDiv') {
    debugger;
  }
  appendChild.bind(this, ...args)();
}

改造完后,可以發現文檔中的 appendChild 都會打出日志了,如下:

但是,此時重新訪問谷歌地圖 iframe,卻看不到任何 append 的日志,這是為什么呢?我突然想起,iframe 處于一個沙箱中,我這直接在控制臺里輸的行為只能改頁面的 Element 的原型,卻沒法改到 iframe 里的 Element。那此時該怎么辦呢?

通過 override 插入改造代碼

在控制臺里打應該是不行了,所以我們的眼光只能放到谷歌地圖的腳本上,只要把我們的改造代碼加到 js 中,那 iframe 一跑就會有我們的代碼了。因此我借助 chrome 本來就提供的 override 功能對谷歌入口 js 進行了改造。為了可能沒用過 override 的同學,這邊詳細說下這個功能如何使用,已經會的同學可以跳過這個部分

how to use override?

首先我們在 Sources 標簽頁下找到 override,并開啟 Enable Local Overrides。

如果你是第一次使用,此時 chrome 應該會讓你提供一個空文件夾,用于存放 override 的文件,隨便找個路徑新建個文件夾叫 override,然后選擇這個 override 的文件夾即可。

如果 chrome 報錯說此文件夾無法讀寫,需要給這個路徑開通讀寫權限,mac 下輸入命令 sudo chmod 777 ${路徑} 即可(沒記錯的話,作者 mac 命令用的不是很好~~~)

然后找到入口文件,然后右鍵選擇 Save for overrides (一定要是原件,formatted 后的版本不行)

然后就可以看到 overrides 文件夾里有這個 js 文件啦~此時可以隨意更改并保存,刷新后即可應用更新!

因為 chrome 自帶的 format 對這個 js 效果很差,還是有一大坨代碼堆積,難以 debug。所以我私下用 vscode 的 prettier 格式化了一下

開始 debug!

通過加入改造代碼,我們在訪問谷歌地圖的時候輕松找到了 js 棧,如下:

后來經過漫長的 F9、F10、上下前后選棧,以及大量的腦筋急轉彎后,找到了問題原因:

這個地方,會在初始化的時候拿 body 的寬度,如果寬高都是 0, 會返回一個 false,導致 append 的邏輯進不去。由于 doc1.0 是通過 document.createElement 創建 iframe,然后再插到文檔中的,而且一開始并沒有寬高,因此可能引發谷歌地圖這個問題,造成黑屏。

解決方案

在 iframe load 后再刷新下谷歌地圖。


https://mp.weixin.qq.com/s/hjChVRVAv3_lqNEYShFglQ

最多閱讀

iOS 性能檢測新方式?——AnimationHitches 8月以前  |  17890次閱讀
快速配置 Sign In with Apple 2年以前  |  5484次閱讀
APP適配iOS11 3年以前  |  4436次閱讀
App Store 審核指南[2017年最新版本] 3年以前  |  4262次閱讀
所有iPhone設備尺寸匯總 3年以前  |  4184次閱讀
使用 GPUImage 實現一個簡單相機 3年以前  |  3915次閱讀
開篇 關于iOS越獄開發 3年以前  |  3794次閱讀
在越獄的iPhone設置上使用lldb調試 3年以前  |  3717次閱讀
給數組NSMutableArray排序 3年以前  |  3641次閱讀
使用ssh訪問越獄iPhone的兩種方式 3年以前  |  3346次閱讀
UITableViewCell高亮效果實現 3年以前  |  3344次閱讀
關于Xcode不能打印崩潰日志 3年以前  |  3241次閱讀
使用ssh 訪問越獄iPhone的兩種方式 3年以前  |  3082次閱讀
為對象添加一個釋放時觸發的block 3年以前  |  2857次閱讀
使用最高權限操作iPhone手機 3年以前  |  2828次閱讀

手機掃碼閱讀
18禁止午夜福利体验区,人与动人物xxxx毛片人与狍,色男人窝网站聚色窝
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>