React Native Webview组件没有自带的方式可以监听网页内部资源的加载(jpg, png, js, css, mp3等),曲线实现方式:用js注入定时器到网页,网页里获取节点的src属性并postMessage给native,以img节点为例:

import { WebView } from 'react-native-webview'
let srcs:string[] = []
export default function WebviewScreen() {
  return (
    <WebView 
      source={{ uri: 'https://www.bing.com/images' }}
      useWebKit={true}
      allowsBackForwardNavigationGestures
      allowsInlineMediaPlayback
      injectedJavaScriptBeforeContentLoaded = {`
        setInterval(()=>{
          const nodes = document.querySelectorAll('img')
          for (const node of nodes) {
            window.ReactNativeWebView.postMessage(node.src)
          }
        }, 2000)
      `}
      onMessage = {msg=>{
        const src = msg.nativeEvent?.data?.trim()
        if (src && -1===srcs.indexOf(src)) {
          console.log('onMessage', new Date(), src)
          srcs.push(src)
        }
      }}
    />
  );
}

也可以用于video等其它带有src的节点
如果是video,src可能在它的子节点srouce里,而且可能有多个,所以需要这么写:

setInterval(() => {
  const videoElems = document.querySelectorAll('video')
  for (const videoElem of videoElems || []) {
    window.ReactNativeWebView?.postMessage(videoElem.src)
    for (const courceElem of videoElem.getElementsByTagName('source') || []) {
      window.ReactNativeWebView?.postMessage(courceElem.src)
    }
  }
}, 1000)

缺点:

  1. 只能定时不能监听
  2. 如果网页里用到跨域的iframe,则iframe里的resource无法被获取

添加新评论