成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何定位 Hybrid Web 頁面中 Native 注入的 JS 代碼

開發 前端
在絕大多數情況下,業務開發并不需要感知這些 Native 注入的代碼,但是在一些 性能優化/鏈路排查 的情況下,就需要感知這些 Native 注入代碼的時機和運行情況了,從而更好的定位問題。

一個網頁除了可以運行在公共的瀏覽器上,也可以運行在 APP 端內的 WebView 組件上。由于這些 Hybrid Web 網頁運行在一個相對封閉的環境里,所以 APP 本身可以向 WebView 中注入一些 JS 代碼,對 Web 頁面做定向增強(最典型的運用就是 JSBridge,提供了一道 Web <--> Native 通信的橋梁)。

在絕大多數情況下,業務開發并不需要感知這些 Native 注入的代碼,但是在一些 性能優化/鏈路排查 的情況下,就需要感知這些 Native 注入代碼的時機和運行情況了,從而更好的定位問題。

由于 Chrome/Safari 的 debug 調試工具基本上是為 純 Web 服務的,而且這個需求很小眾,所以這個能力支持的并不是很好。這個小需求網絡上沒什么總結性的文章,ChatGPT 回答的也差強人意,正好這段時間也做了一些相關的工作,所以順勢就記下來,幫助某個有緣人。

直接查看 Native 代碼

如果你對 Native WebView 的封裝代碼很熟悉,或者有一定的 Native 經驗,直接閱讀源碼是最快的方式。這里我說幾個最常用的 JS 注入 API:

iOS

iOS 主要關注這 3 個 API:

addScriptMessageHandler[1]

- (void)addScriptMessageHandler:(id<WKScriptMessageHandler>)scriptMessageHandler 
                           name:(NSString *)name;

通過這個方法可以給WKWebView環境中添加一個指定 name 的 JS 對象,前端可以調用該對象的 postMessage 方法,向客戶端發送消息。前端類似于這樣調用:

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)

addUserScript[2]

// WKUserContentController
- (void)addUserScript:(WKUserScript *)userScript;

可以用這個函數注入 JS 腳本字符串到 WKWebView 中。

evaluateJavaScript[3]

// WKWebView
- (void)evaluateJavaScript:(NSString *)javaScriptString 
         completionHandler:(void (^)(id, NSError *error))completionHandler;

這個函數也可以在 WKWebView 上下文中運行一段 JS 代碼。

其實還有很多注入函數,但常用的就這 3 個,其它的函數就是和他們有些細微的差別,感興趣的可以直接看官方文檔。

另外還需注意的是 JS 代碼注入的時機,頁面加載前還是頁面加載后注入代碼,帶來的影響可能是大不一樣的。而且這個 API 也特別多,可參考文檔:WKNavigationDelegate[4],重點關注 didStartProvisionalNavigation[5] 和 didFinishNavigation[6]。

圖片圖片

https://bbs.huaweicloud.com/blogs/331397

Android

Android 主要關注這 2 個 API:

addJavascriptInterface[7]

/** Instantiate the interface and set the context.  */class WebAppInterface(private val mContext: Context) {    // 通過 @JavascriptInterface 注解,向 WebView 暴露 showToast 方法    @JavascriptInterface    fun showToast(toast: String) {        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show()    }}val webView: WebView = findViewById(R.id.webview)// "Android" 將會暴露在 Webview 的 window 變量上webView.addJavascriptInterface(WebAppInterface(this), "Android")

然后前端直接調用即可:

<input type="button" value="Say hello" notallow="showAndroidToast('Hello Android!')" /><script type="text/javascript">  function showAndroidToast(toast) {    window.Android.showToast(toast);  }</script>

evaluateJavascript[8]

public void evaluateJavascript (String script, ValueCallback<String> resultCallback)

類似于 iOS,也是在 WebView 上下文中運行一段 JS 腳本。

同樣的,Android 也要注意 JS 代碼注入的時機。API 太多了,參考這個鏈接:WebViewClient#public-methods[9],重點關注 onPageStarted[10] 和 onPageFinished[11]。

有能力閱讀 Native 源代碼是最理想的情況,但是現實一般很殘酷:

  • 絕大部分前端同學不懂 Native 代碼
  • 現在還存留的高流量 APP,基本都迭代 5 年以上了,代碼一層一層糊成 ?? 山,老師傅都得在里面繞半天
  • 降本增笑,老師傅都沒了

所以其實還有第 2 種基于觀測的方案:利用 WebView Devtool 工具定位。

用 Web 調試工具定位

前面也說了,查看注入的 JS 代碼是一個很小眾的需求,所以調試工具并沒有提供獨立的查看面板,所有的能力都是拼拼湊湊起來的,而且部分能力 iOS 和 Android 互為補集 ??,整體上還有有些凌亂的。

如何遠程調試 Web 頁面,可以參考這篇文章:各種「真機遠程調試」方法匯總[12]

想遠程調試 APP WebView 網頁,需要在 Native 層開啟調試能力

  • iOS:16.4 以上版本需要設置 webView.isInspectable = true[13] 開啟遠程調試
  • Android:設置 setWebContentsDebuggingEnabled(true)[14] 開啟遠程調試

Common

iOS 和 Android 都通用的方案有這么兩種:

Debug

我們可以通過 debug 到關鍵代碼,然后查看調用棧,找到注入代碼:

iOS 利用 Safari Devtool 調試,查看方式如下:

iOS Safari DebugiOS Safari Debug

Android 利用 Chrome Devtool 調試,查看方法如下:Android Chrome Debug


Log

還有一種方法是在 Native 注入的 JS 代碼中,加入 console.log 的調用,這樣在注入代碼運行的時候,可以從 Console 面板的資源引用找到注入腳本。

但是這個問題有個悖論:

  • 一般注入的腳本為了不增加運行時性能負擔,是不會加 log 調用的,所以一般沒法用
  • 如果開發者主動去注入的 JS 代碼中加入 log,那說明他有一定的 native 經驗,那為什么不直接看 native 代碼呢?

所以這樣方法更像一種輔助方案,用來配合其它方案一起排查問題。

iOS

iOS 有兩種方式看注入的代碼。

第一種是在「來源」的「附加腳本」里,可以在這里看到 Native 通過 addUserScript 注入的腳本,整整齊齊的,還是比較方便查看的。但有個問題是這里并不會列出 evaluateJavaScript 注入的代碼。

iOS 附加腳本iOS 附加腳本

這里就介紹第二種方法,那就是「全局搜索」。

Safari 的全局搜索功能,可以同時搜索 addUserScript/evaluateJavaScript/正常加載的資源 里的代碼,所以如果你知道注入代碼的一些關鍵信息,可以通過搜索的方式定位代碼。

iOS 全局搜索iOS 全局搜索

Android

Android 這里使用 Chrome Devtool 查看注入代碼。用了這么久的 Chrome Devtool,我是第一次發現它做的不如 Safari 的地方,那就是上面 Safari Devtool 有的東西它都沒有。

但是 Chrome Devtool Performance 可以曲線救國一下,我們可以通過性能錄制得到一份性能分析火焰圖,然后查看主線程的代碼執行情況,一般是 Evalutae Script 階段,然后再定位可能的執行時機,通過點擊 Bar 展開的 Summary 面板,一般有個 VM 開頭的文件,打開就可顯示注入的 JS 代碼:

Chrome 火焰圖Chrome 火焰圖

總結

從上面內容可以看出定位「注入 JS 代碼」還是挺麻煩的,需要用各種手段曲線救國,而且很多情況下各個技巧需要交叉使用才能定位到。希望我這篇文章可以幫助到一些開發者,減少 debug 內耗的時間。

責任編輯:武曉燕 來源: 鹵代烴實驗室
相關推薦

2014-12-18 13:40:16

Web AppHybrid AppNative App

2013-09-04 15:07:06

移動應用設計

2013-12-16 15:07:59

NativeHybrid開發移動

2022-08-31 09:31:20

AlibabaKoodinatorcontainers

2020-06-09 15:13:15

2014-12-17 11:09:39

Hybrid AppWebView裝載頁面

2010-10-09 10:56:50

DHTMLJS

2013-10-09 09:10:28

移動應用開發NativeHybrid

2021-03-17 08:00:59

JS語言Javascript

2012-06-18 15:18:32

JS

2021-02-26 13:18:38

Node.js漏洞代碼

2010-10-09 11:01:31

JS

2012-06-28 15:47:31

Web AppHybrid AppHTML5

2011-05-10 15:05:04

Webhover

2022-09-21 08:37:22

HardFaultSTM32開發

2013-05-29 13:28:06

移動開發企業級應用移動中間件

2014-12-17 10:12:06

HybridAppFramewor頁面布局

2020-12-16 13:22:37

Web安全SQL工具

2023-07-30 22:25:00

JavaScrip服務端Web

2023-09-04 10:10:47

插件頁面元素
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级全黄少妇性色生活免费看 | 日本淫视频| 午夜网| 成人在线一区二区 | 麻豆成人在线视频 | www.黄色在线观看 | 亚洲福利网站 | 一区二区在线不卡 | 黑人成人网| 亚洲成人免费观看 | 国产精品精品3d动漫 | 午夜影视 | 在线播放国产一区二区三区 | 日韩精品一区二区三区在线观看 | av高清毛片 | 日韩免费网站 | 精品国产免费一区二区三区演员表 | 国产97人人超碰caoprom | 91国内精品久久 | 久久国产精99精产国高潮 | 久久精品一级 | 2一3sex性hd| 91精品国产91久久久久久吃药 | 欧美国产视频一区二区 | 欧美日韩高清在线一区 | 日韩欧美成人精品 | 欧美激情精品久久久久 | 成人免费小视频 | 69av网| 一区二区三区回区在观看免费视频 | 日韩精品在线一区二区 | 国产视频第一页 | 综合精品 | 国产欧美日韩在线播放 | 91传媒在线观看 | 一级a爱片久久毛片 | 二区三区视频 | 日韩中文字幕一区 | 97日日碰人人模人人澡分享吧 | 一级一片在线观看 | 午夜伦理影院 |