Blog

Blog

PHODAL

React Native WebView onMessage 收不到 window.postMessage 消息

在为 Growth 添加一个 WebView 的时候,由于 JavaScript 代码比较多,发现自己写的 onMessage 根本收不到任何消息:

  handleMessage = (event: Object) => {
    const message = JSON.parse(event.nativeEvent.data);
    console.log(message);
  } 

对应的 WebView 代码:

  $(function() {
    window.postMessage(JSON.stringify({ status: 'ready' }));
    document.addEventListener('message', function (event) {
      var data = JSON.parse(event.data);
      if (data.action === 'algorithm') {
        window.algorithm = data.algorithm;
        $(window).trigger('bridge.run', window.algorithm);
      } else if (data.action === 'run') {
        $('#btn_run').trigger('click');
      } else if (data.action === 'run') {
        $('#btn_pause').trigger('click');
      }
    });
  })

发现这样写也是不行的。探索了好几天,才想到这个问题一定是一个 issue,然后找到了:react native html postMessage can not reach to WebView #11594

发现了同样的问题,对于这个问题的解决办法就是写一个 awaitPostMessage 方法:

function awaitPostMessage() {
  var isReactNativePostMessageReady = !!window.originalPostMessage;
  var queue = [];
  var currentPostMessageFn = function store(message) {
    if (queue.length > 100) queue.shift();
    queue.push(message);
  };
  if (!isReactNativePostMessageReady) {
    var originalPostMessage = window.postMessage;
    Object.defineProperty(window, 'postMessage', {
      configurable: true,
      enumerable: true,
      get: function () {
        return currentPostMessageFn;
      },
      set: function (fn) {
        currentPostMessageFn = fn;
        isReactNativePostMessageReady = true;
        setTimeout(sendQueue, 0);
      }
    });
    window.postMessage.toString = function () {
      return String(originalPostMessage);
    };
  }

  function sendQueue() {
    while (queue.length > 0) window.postMessage(queue.shift());
  }
}

然后再执行我们的 postMessage 方法,如下所示:

  $(function() {
    function awaitPostMessage() {
      var isReactNativePostMessageReady = !!window.originalPostMessage;
      var queue = [];
      var currentPostMessageFn = function store(message) {
        if (queue.length > 100) queue.shift();
        queue.push(message);
      };
      if (!isReactNativePostMessageReady) {
        var originalPostMessage = window.postMessage;
        Object.defineProperty(window, 'postMessage', {
          configurable: true,
          enumerable: true,
          get: function () {
            return currentPostMessageFn;
          },
          set: function (fn) {
            currentPostMessageFn = fn;
            isReactNativePostMessageReady = true;
            setTimeout(sendQueue, 0);
          }
        });
        window.postMessage.toString = function () {
          return String(originalPostMessage);
        };
      }

      function sendQueue() {
        while (queue.length > 0) window.postMessage(queue.shift());
      }
    };
    awaitPostMessage(); // Call this only once in your Web Code.

    window.postMessage(JSON.stringify({ status: 'ready' }));
    document.addEventListener('message', function (event) {
      var data = JSON.parse(event.data);
      if (data.action === 'algorithm') {
        window.algorithm = data.algorithm;
        $(window).trigger('bridge.run', window.algorithm);
      } else if (data.action === 'run') {
        $('#btn_run').trigger('click');
      } else if (data.action === 'run') {
        $('#btn_pause').trigger('click');
      }
    });
  })

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签