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

Turbo rails, secure context: TypeError: Cannot read properties of null (reading 'postMessage') in iframe postMessage handler #343

Open
malakutsko opened this issue Apr 17, 2024 · 0 comments

Comments

@malakutsko
Copy link

malakutsko commented Apr 17, 2024

We have a rails application with https://turbo.hotwired.dev/ on the frontend. We are using StreamSaver v2.0.4 to handle file downloads in secure context.

We have the next issue with StreamSaver, reproducible with these steps:

  1. User clicks Download link
  2. StreamSaver creates an iframe and downloads the file through it, everything is ok.
  3. User navigates to another page, and there is another Download link
  4. User clicks Download, but nothing happens
  5. User is unable to download anything until they fully reload the page.

Console shows the error:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'postMessage')
    at iframe.postMessage (StreamSaver.js:50:60)
    at Object.createWriteStream (StreamSaver.js:251:25)

After some debugging I came to conclusion that this happens because StreamSaver is currently incompatible with turbo-rails, but it can be easily fixed.

The problem is that on the step 3 turbo replaces the dom, and the iframe created on the step 2 gets removed, but the reference to it still lives as mitmTransporter: https://github.com/jimmywarting/StreamSaver.js/blob/2.0.4/StreamSaver.js#L116

Then on step 4 the StreamSaver checks the existence of mitmTransporter, and it's indeed defined, so it skips creating iframe, but the postMessage to it fails, because it's not in the dom anymore.

I would propose to change this condition https://github.com/jimmywarting/StreamSaver.js/blob/2.0.4/StreamSaver.js#L115 so that in secure context it also checks existence of mitmTransporter.contentWindow. Then it will create the iframe again if it's not in the dom.

Does this make sense? I would create a PR.

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

No branches or pull requests

1 participant