javascript 在 React Native 应用程序中调试 WebView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47711418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 07:33:25  来源:igfitidea点击:

Debugging WebView in React Native apps

javascriptandroidreact-nativewebview

提问by Mohsin Shafique

I have a React Native App that uses WebView to render an HTML page from the assets. The page has some javascript that does some processing. The problem is that I cannot see the console.logstatements from the web view. I have tried the Chrome Remote Remote Debugging WebViews

我有一个 React Native 应用程序,它使用 WebView 从资产呈现 HTML 页面。该页面有一些 javascript 进行一些处理。问题是我看不到console.logweb 视图中的语句。我已经尝试过 Chrome 远程远程调试 WebViews

Here's how the code looks like. Note that for Android, I am trying to supply some native props to enable debugging.

下面是代码的样子。请注意,对于 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',
  },
});

Any ideas around how that might work will be highly appreciated.

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

回答by mootrichard

The easiest way to inspect your WebView in React Native is to just use the Remote JS Debugger.This has the added benefit for working in either iOS or Android, since you're simply debugging the JavaScript that is running on your application.

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

In order to see the WebViews, you'll want to go a step further and use Chrome's Remote Devices.

为了查看 WebView,您需要更进一步并使用Chrome 的远程设备

DevTools Chrome

开发者工具 Chrome

If you click on Inspect next to your Document matching the index.htmlyou're wanting to debug, you can then see all of the logs in the console for that WebView.

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

enter image description here

在此处输入图片说明

I added a <script>inside of index.htmlin the <header>that just does the following:

<script>index.htmlin 中添加了一个inside <header>,它只执行以下操作:

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

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

You can see in the image above, its logging out in the DevTools that is inspecting that WebView.

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

回答by Artal

Not sure if it's relevant for your case, but if you're also developing for iOS there's a pretty easy way to do it on a Mac + iOS simulator (or a real device). At the end, a React Native WebViewcreates a native web-view (UIWebViewon iOS, and a WebViewon Android), so any debugging method which works for web apps applies here as well.

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

  1. On your iOS simulator (or device): Open the settings app -> Safari -> Advanced -> Turn Web inspector ON.
  2. Open Safari on your Mac and enable developer mode in: Preferences -> Advanced -> Show developer menu in menu bar (checkbox at the bottom).
  3. In Safari on your mac you will now have the "Develop" menu. Open it and find the Simulator or your connected device. When you hover this menu item you will see the currently loaded page. This works for any page loaded on the device, whether it's shown in a WebViewinside your app or on the system browser.
  4. Once you select the page, you can use the Safari Web Inspector to pretty much do anything: view all loaded resources, network requests, highlight elements, console logs, debug the JS code and more.
  1. 在您的 iOS 模拟器(或设备)上:打开设置应用程序 -> Safari -> 高级 -> 打开 Web 检查器。
  2. 在 Mac 上打开 Safari 并在以下位置启用开发人员模式:首选项 -> 高级 -> 在菜单栏中显示开发人员菜单(底部的复选框)。
  3. 在 Mac 上的 Safari 中,您现在将拥有“开发”菜单。打开它并找到模拟器或您连接的设备。当您悬停此菜单项时,您将看到当前加载的页面。这适用于设备上加载的任何页面,无论它是显示在WebView您的应用程序内部还是系统浏览器中。
  4. 选择页面后,您几乎可以使用 Safari Web Inspector 执行任何操作:查看所有加载的资源、网络请求、突出显示元素、控制台日志、调试 JS 代码等等。

回答by Jon Goodwin

I propose to unify javascript'sconsole messages (console.log) and logcatof Android into one logcatwhich can be viewed with [Monitor].(https://developer.android.com/studio/profile/am-basics.html). It can be helpful to have console messages and WebViewmessages in one place, especially when you have race conditions/timing problems, so you can see the order of events. Monitor also allows you to apply filters, to select which messages you see. iOS users can also fond this helpful.

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

Here is an example: enter image description hereSee CustomWebViewManager and CustomWebView in React Nativefor some background on how to customize WebViewin React Native(a JavaScript libraryfor building user interfaces. "It is maintained by Facebook, Instagramand a community of individual developers and corporations" wiki).

这是一个示例: 在此处输入图片说明有关如何在React Native 中进行自定义的一些背景信息,请参阅React Native 中的 CustomWebViewManager 和 CustomWebView(用于构建用户界面。“它由,以及个人开发人员和公司的社区维护” wiki)。WebViewJavaScript libraryFacebookInstagram

Info: WebChromeClientlets you handle Javascript'sconsole.log("message")
{via onConsoleMessage(ConsoleMessage cm)}, alert()and other functions.

信息:WebChromeClient可让您处理Javascript'sconsole.log("message")
{via onConsoleMessage(ConsoleMessage cm)}alert()和其他功能。

Catching JavaScript's console messages:

捕获 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);

The problem with cross platformsupport is the Virtual Machineand the associated Sandbox. I think react-nativetriesto be very pure JavaScript(but fails, JavaScriptas a language is pure, the implementationsnever are, always about compromise). My personal preference for cross platform support is Cordova.

跨平台支持的问题在于虚拟机和相关的沙箱。我认为react-native试图变得非常纯粹JavaScript(但失败了,JavaScript因为语言是纯粹的,实现永远不是,总是妥协)。我个人对跨平台支持的偏好是Cordova

回答by WebsByTodd

You can make use of window.postMessagefrom inside your WebView and the onMessageprop of the WebView component:

您可以window.postMessage从 WebView 内部和onMessageWebView 组件的prop 中使用:

In your html:

在你的 html 中:

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

In your react native component:

在您的本机组件中:

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',
  },
});