在 React Native 应用程序中调试 WebView

Posted

技术标签:

【中文标题】在 React Native 应用程序中调试 WebView【英文标题】:Debugging WebView in React Native apps 【发布时间】:2018-05-22 12:37:20 【问题描述】:

我有一个使用 WebView 从资产呈现 html 页面的 React Native 应用程序。该页面有一些 javascript 进行一些处理。问题是我无法从 Web 视图中看到 console.log 语句。我试过 Chrome 遥控器Remote Debugging WebViews

代码如下所示。请注意,对于 android,我正在尝试提供一些原生道具来启用调试。

import React from 'react';
import Expo from 'expo';
import  WebView  from 'react-native';

export default class App extends React.Component 

  render() 
    const htmlURL = Expo.Asset.fromModule(require('./assets/index.html')).uri;
    return (
      <WebView nativeConfig=props: webContentsDebuggingEnabled: true  
      source=uri: htmlURL />
    );
  



const styles = StyleSheet.create(
  container: 
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  ,
);

任何关于如何工作的想法都将受到高度赞赏。

【问题讨论】:

你试过 expo XDE @Mohsin Hijazee 【参考方案1】:

在 React Native 中检查 WebView 的最简单方法是使用 Remote JS Debugger. 这对于在 ios 或 Android 中工作都有额外的好处,因为您只需调试在应用程序上运行的 JavaScript。

为了查看 WebView,您需要更进一步并使用 Chrome's Remote Devices。

如果您单击与您要调试的 index.html 匹配的文档旁边的检查,则可以在控制台中查看该 WebView 的所有日志。

我在&lt;header&gt; 中的index.html 中添加了一个&lt;script&gt;,它只是执行以下操作:

console.log('This is showing in the console!')

您可以在上图中看到,它在正在检查该 WebView 的 DevTools 中注销。

有关 react-native-webview 调试指南的更多信息,请访问Debugging Guide Docs

【讨论】:

这有点笨拙,但我很确定这是目前 React Native 中可用的最佳解决方案。 正如你所说,我该如何设置Chrome's Remote Devices config?我应该把那个代码放在哪里?你能分享你的代码吗?我卡住了 2 天。 您提供的链接说必须通过调用静态方法 setWebContentsDebuggingEnabled 来启用 WebView 调试。如果不退出世博会,你就无法做到这一点,对吗?那么expo项目就没有办法在不弹出的情况下调试webview吗? 它已被弃用。【参考方案2】:

不确定它是否与您的情况相关,但如果您也在为 iOS 开发,那么有一种非常简单的方法可以在 Mac + iOS 模拟器(或真实设备)上进行。最后,React Native WebView 创建一个原生 web 视图(iOS 上为 UIWebView,Android 上为 WebView),因此任何适用于 web 应用程序的调试方法也适用于此。

    在您的 iOS 模拟器(或设备)上:打开设置应用程序 -> Safari -> 高级 -> 打开 Web 检查器。 在 Mac 上打开 Safari 并在以下位置启用开发者模式:首选项 -> 高级 -> 在菜单栏中显示开发者菜单(底部的复选框)。 在 Mac 上的 Safari 中,您现在将拥有“开发”菜单。打开它并找到模拟器或您连接的设备。当您悬停此菜单项时,您将看到当前加载的页面。这适用于设备上加载的任何页面,无论是在您的应用内或系统浏览器中显示在 WebView 中。 选择页面后,您几乎可以使用 Safari Web Inspector 执行任何操作:查看所有加载的资源、网络请求、突出显示元素、控制台日志、调试 JS 代码等等。

【讨论】:

谢谢,这是一个有用的提示,但不适用于我的目的,因为我需要在初始化时调试并且无法足够快地单击 Web 视图 :) @AaronBrager 你可以在 mac safari 中点击重新加载按钮,你会看到初始化日志 我试过这个,它适用于在 Safari 中打开的网页,但不适用于 WebView 中的页面。 编辑:以上评论是关于在真实设备中打开的页面。如果在模拟器中,Safari 和 WebView 都可以工作。我给你投了赞成票。 :) @Betty 很棒。我只是想建议您检查设备上 Safari 高级设置中的“Web Inspector”是否已启用。对我来说,它适用于设备以及模拟器【参考方案3】:

我建议将Android的javascript's控制台消息(console.log)和logcat统一为一个logcat,可以用[监视器]查看。(https://developer.android.com/studio/profile/am-basics.html)。将控制台消息和WebView 消息放在一个位置会很有帮助,尤其是当您遇到竞争条件/计时问题时,您可以查看事件的顺序。 Monitor 还允许您应用过滤器,以选择您看到的消息。 iOS 用户也会喜欢这个有用的。

这是一个例子: 有关如何在React Native 中自定义WebView 的背景信息,请参见CustomWebViewManager and CustomWebView in React Native(用于构建用户界面的JavaScript library。“它由FacebookInstagram 和个人开发人员和公司社区维护”@ 987654326@)。

信息:WebChromeClient 可让您处理 Javascript's console.log("message") 通过 onConsoleMessage(ConsoleMessage cm)alert() 和其他功能。

捕捉 JavaScript 的控制台消息:

//find or get your React Native webView or create a CustomWebView
WebView webView = (WebView) this.findViewById(R.id.webView1);

//by setting a WebClient to catch javascript's console messages:
// and relay them to logcat (view in monitor) or do what you want with them
WebChromeClient webChromeClient = new WebChromeClient() 
        public boolean onConsoleMessage(ConsoleMessage cm) 
            Log.d(TAG, cm.message() + " -- From line "
                    + cm.lineNumber() + " of "
                    + cm.sourceId() );
            return true;
        
    );

webView.setWebChromeClient(webChromeClient);

cross platform 支持的问题在于Virtual Machine 和相关联的Sandbox。 我认为react-native 尝试 非常纯粹JavaScript(但失败了,JavaScript 作为一种语言是纯粹的,实现 从来都不是,总是关于妥协)。我个人对跨平台支持的偏好是Cordova。

【讨论】:

【参考方案4】:

在最近的 Chrome 版本中,您只需在 React Native 应用中启用调试模式,然后导航到 chrome://inspect/#devices

在“设备”选项卡中,找到与您的应用程序对应的条目“WebView in .....”,然后单击“检查”以查看调试器。

【讨论】:

真的很有趣,但似乎不适用于 Expo。希望别人有更多的运气。【参考方案5】:

您可以在 WebView 内部使用 window.postMessage 和 WebView 组件的 onMessage 属性:

在您的 html 中:

...
window.postMessage(stringMessage, '*');
...

在你的 react 原生组件中:

import React from 'react';
import Expo from 'expo';
import  WebView  from 'react-native';

export default class App extends React.Component 
  handleMessage = (event) => 
     console.log(event.nativeEvent.data);
  
  render() 
    const htmlURL = Expo.Asset.fromModule(require('./assets/index.html')).uri;
    return (
      <WebView nativeConfig=props: webContentsDebuggingEnabled: true  
      source=uri: htmlURL
      onMessage=this.handleMessage
      />
    );
  



const styles = StyleSheet.create(
  container: 
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  ,
);

【讨论】:

运行时错误怎么办?有机会见到他们吗?我的意思是,也许 try/catch 可以,但我想知道是否有其他方法可以访问错误流。

以上是关于在 React Native 应用程序中调试 WebView的主要内容,如果未能解决你的问题,请参考以下文章

如何在调试模式下,在 react-native-firebase 中禁用 Crashlytics?

在 React Native 应用程序中调试 WebView

React Native Debugger

《React Native》之程序调试篇

React Native:防止远程调试器在 Chrome 中打开

React-Native 远程调试器无法在 iPhone 上运行