Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message Listener Only Receives "{isTrusted: true}" Object #689

Closed
reggie3 opened this issue Jun 30, 2019 · 9 comments
Closed

Message Listener Only Receives "{isTrusted: true}" Object #689

reggie3 opened this issue Jun 30, 2019 · 9 comments

Comments

@reggie3
Copy link

reggie3 commented Jun 30, 2019

The webpage rendered inside webview only receives {isTrusted: true} when receiving events.

This issue can be reproduced by adding the following code to the webage that attaches a function to the message event:
window.addEventListener('message', this.handleMessage);

In the webview, I activate the message event using the injectJavaScript method like this this.webview.injectJavaScript(window.postMessage(${stringMessage}, '*'); true;)

where stringMessage is as JSON.stringified object

Expected behavior:
I expected the entire stringified object to be received as a variable in the handleMessage function. Instead, I only receive the {isTrusted: true}

Environment:

@rgoldiez
Copy link

rgoldiez commented Jul 5, 2019

@reggie3 - have you tried (in your webview's JS to log/message the data property of the object (yes, object) that comes in?

@reggie3
Copy link
Author

reggie3 commented Jul 5, 2019

@rgoldiez Actually, I'm not getting a data property. I am using the following code to handle and debug incoming messages for the page that the WebView renders:

  handleMessage = (event) => {
    this.addDebugMessage('HandleMessage 1:');
    this.addDebugMessage({event})
    let msgData = JSON.parse(event);
    this.addDebugMessage({msgData})
    try {
      this.addDebugMessage(`received message: `, msgData);
      if(msgData.payload){
      this.setState({ ...this.state, ...msgData.payload }, () => {
        this.addDebugMessage(this.state);
      });}
    } catch (error) {
      this.addDebugMessage(JSON.stringify(error));
    }
  };

When the webview runs the following code:
this.webview.injectJavaScript(`window.postMessage("test2", '*');`);

The screenshot below show's the "conversation" between the webview and the page its rendering:

Screenshot_20190705-132748

The text in the orange background is what the rendered page is doing. "Handle Message 1" correlates to this.addDebugMessage('HandleMessage 1:'); in the code above. So I can confirm that the webpage is receiving something. The printed event object is created by the this.addDebugMessage({event}) code.

Unfortunately, I'm not seeing a data property.

@rgoldiez
Copy link

rgoldiez commented Jul 5, 2019

@reggie3 ... Humor me and trying changing this.addDebugMessage({event}) to this.addDebugMessage(event.data)

@reggie3
Copy link
Author

reggie3 commented Jul 5, 2019

@rgoldiez That worked. Thank you for your help.

@reggie3 reggie3 closed this as completed Jul 5, 2019
@rgoldiez
Copy link

rgoldiez commented Jul 5, 2019

@reggie3 - Glad to hear! I've faced the same issue so I thought it might be what you were facing.

@philnova
Copy link

philnova commented Dec 3, 2019

@reggie3 @rgoldiez I'm facing this exact same issue. Sending message via:

this.webview.injectJavaScript(`
    (function(){
      window.dispatchEvent(new MessageEvent('message', {data: ${JSON.stringify(message)}}));
    })();
    true;
    `);

And receiving it with:

window.addEventListener('message', onReceiveMessage);

The onReceiveMessage function does:

const onReceiveMessage = (nativeEvent: MessageEvent) => {


    let nativeMessage;
    try {
      nativeMessage = JSON.parse(nativeEvent.data);
    } catch (err) {
      postMessage({
        id: 'unknownId',
        type: 'error',
        payload: {
          error: {
            name: 'MessageParsingError',
            message: JSON.stringify(nativeEvent),
          },
        },
      });
      return;
    }
...

The receiver method always errors trying to JSON.parse the data payload because it's undefined. When I stringify and send back the nativeEvent, it's just "{ "isTrusted": true }".

Any ideas on how to proceed?

@philnova
Copy link

philnova commented Dec 3, 2019

Aha -- the error wasn't due to a missing payload, it was due to the JSON.parse. Apparently when you send the payload via injectJavaScript vs. postMessage it's already parsed, so you can just use it as a JS object directly.

@LindaOjo
Copy link

Solutions above didn't work for me.

What worked for me.

I had a false false report. WebView logs {isTrusted: false} when the event data is from an "untrusted source". Even though the data is as expected.

console.log(data) // {isTrusted: false}

Ignoring the log and treating the data as expected (assuming the correct data was logged) worked for me.

@CallumHemsley
Copy link

Aha -- the error wasn't due to a missing payload, it was due to the JSON.parse. Apparently when you send the payload via injectJavaScript vs. postMessage it's already parsed, so you can just use it as a JS object directly.

This isn't true for me! I do something hardcoded like

webviewRef.current.injectJavascript(window.postMessage(JSON.stringify({
        source: "native",
        data: {
          deviceId: "dummy-device-id-12345",
          deviceToken: "dummy-device-token-67890",
          message: "Hello from React Native with dummy device info!"
        }
      }), '*'));`

This comes back as a string for me on the webside - I have to JSON.parse(event.data)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants