【问题标题】:Debugging WebView in React Native apps在 React Native 应用程序中调试 WebView
【发布时间】: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

标签: javascript android react-native webview


【解决方案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 应用程序的调试方法也适用于此。

  1. 在您的 iOS 模拟器(或设备)上:打开设置应用程序 -> Safari -> 高级 -> 打开 Web 检查器。
  2. 在 Mac 上打开 Safari 并在以下位置启用开发者模式:首选项 -> 高级 -> 在菜单栏中显示开发者菜单(底部的复选框)。
  3. 在 Mac 上的 Safari 中,您现在将拥有“开发”菜单。打开它并找到模拟器或您连接的设备。当您悬停此菜单项时,您将看到当前加载的页面。这适用于设备上加载的任何页面,无论是在您的应用内或系统浏览器中显示在 WebView 中。
  4. 选择页面后,您几乎可以使用 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。“它由Facebook、Instagram 和个人开发人员和公司社区维护”@ 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 可以,但我想知道是否有其他方法可以访问错误流。
    猜你喜欢
    • 1970-01-01
    • 2016-09-10
    • 2016-08-28
    • 2017-10-20
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多