stripe-archive / react-stripe-elements

Moved to stripe/react-stripe-js.
https://github.com/stripe/react-stripe-js
MIT License
3.03k stars 319 forks source link

Intermittently getting "Failed to execute 'postMessage' on 'DOMWindow'" error #98

Closed brianwallerstein closed 3 years ago

brianwallerstein commented 7 years ago

From time to time using the back button causes this error:

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://js.stripe.com') does not match the recipient window's origin ('mysite.com')

Has anyone else run into this error? I think it might be from this library but I'm not 100% sure.

jez commented 7 years ago

Thanks for the report @brianwallerstein! This is a known issue that we've had in our internal bug tracker at Stripe for a while. As far as we know, it should be benign (i.e., stripe.js and react-stripe-elements should still work as advertised).

If this is not the case, feel free to re-open! Otherwise, I'll close this for now.

brianwallerstein commented 7 years ago

Thanks for getting back to me so fast! Quick follow up: I'm getting started on using react and this error effectively causes the entire application to crash and display a blank page. Is there a best practice for handling this error gracefully on my end so the application is still functional?

jez commented 7 years ago

Ah, I misread your initial error message---this actually looks like something new.

Could you describe a little bit more about when you're seeing this error? I'm curious to figure out whether this is an integration error on your end, or a bug on our end. (In the first case, we'd like to emit a better error message, and of course in the second, we'd like to fix the bug!)

brianwallerstein commented 7 years ago

Sadly my first post pretty much describes all of it. It happens from time to time, seemingly randomly, when using the back button in my application. FWIW it seems to happen far more often on mobile than desktop browsers.

For now you can try to reproduce by visiting my beta site (https://www.recitesocial.com/social_username/tim_cook), click around on a bunch of different buttons, then try to use the back button several times in succession. It might take a few tries, but you should be able to repro it.

michelle commented 7 years ago

Hmm, I've been clicking around but haven't been able to reproduce this yet. Are you still seeing this issue on your site?

I also noticed that clicking back doesn't bring me to the previous view at times -- is that intentional?.

michelle commented 7 years ago

Do you also have more details on what your usage of this library looks like?

brianwallerstein commented 7 years ago

Sorry, just last night I was able to diagnose and fix the issue. Turned out it was with a different library I'm using that would cause the issue with the back button intermittently. The stripe error I listed above was a symptom of that root issue rather than the cause. Sorry about that!

QuinnNTonic commented 6 years ago

Hello, I am currently experiencing this same issue and wondered if you could give some more info about what other library the error was coming from so that I can attempt to debug with a little more precision.

Thank You

RichardCKLi commented 6 years ago

@brianwallerstein Hi Brian, I have the same comment as @heffernq13. Could you provide more details about how you use the other library that caused the issue? Or more simply, what's the root cause?

jike212 commented 6 years ago

Also having the same issue

paolavness commented 6 years ago

CRITICAL - Just experiencing this for the first time on our app in both production and developements. In our case, the placeholders for the cc details are missing as a result - ie we cannot take payment. Yikes!

Any news on this?

We've been using stripe for a while and were literally taking payments a couple of days back... Nothing has changed on our side. So much be something on stripe side?

Need asap answer here. Thank you!

paolavness commented 6 years ago

Just to add to the above - Using "react-stripe-elements": "^1.2.0", experiencing issue in Chrome 67 only. Firefox 60 and Safari 11 (all on Mac High Safari) working fine.

atty-stripe commented 6 years ago

@paolavness can you link to your page or make a minimal reproduction? As noted, this error happens when JavaScript on your page / in a browser extension tries to access the Stripe iframes.

We haven't seen the degradation elsewhere on Chrome 67, so I would also check for any browser extensions and any changes in your codebase.

paolavness commented 6 years ago

@atty-stripe thank you for the quick reply. Is there a way I can PM you details, possibly via our Stripe account?

atty-stripe commented 6 years ago

Feel free to write into support@stripe.com and cc me at atty@stripe.com. Alternatively you can talk to our support engineers at https://www.irccloud.com/irc/freenode/channel/stripe.

paolavness commented 6 years ago

Great doing so now :) I've also just tried upgrading to elements 2.0.1 with no luck.

paolavness commented 6 years ago

Have just sent with response & request headers.

paolavness commented 6 years ago

For others who experienced this, here is a summary of how I experienced this and how it was resolved.

Issue Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://js.stripe.com') does not match the recipient window's origin ('mysite.com')

The result was the placeholders for enter card number, cvc and expiry did not appear on our webapp. Although the call to https://js.stripe.com returned a 200 the network query showed it was pending. (Interestingly and perhaps related, api calls to Intercom will also returning a 200 tho pending)

Browsers: The issue only happened on Chrome 67 (Firefox 60 and Safari 11 - all on Mac High Safari - worked fine)

Elements version 1.2.0 and 2.0.1 with react

Resolved

Given that I've been using Chrome with the above extensions for ages without this being an issue, it seems more likely that restarting Chrome resolved it. Time will tell.

Thanks to @atty-stripe and the folks at Stripe for a quick response and support here!

m-nathani commented 4 years ago

Hi guys, this is still replicated, i tried restarting Chrome Version 80.0 , but my page is still crashing. It shows a white page with error mentioned in this issue. please help its urgent for me find a workaround.?

friksa commented 4 years ago

I am seeing this consistently starting yesterday when using this in our index.html angular page

<script src="https://js.stripe.com/v3/"></script>
ndbroadbent commented 4 years ago

Hello, this is also happening for me, due to Turbolinks: https://github.com/turbolinks/turbolinks/issues/321

The error only happens when I navigate to a new page. Turbolinks swaps the <body> element so it makes sense that this might cause some problems.

Would it be possible for an engineer at Stripe to see if we can get the JS to play nicely with Turbolinks?

For reference, this is how Drift chat solves the problem: https://gethelp.drift.com/hc/en-us/articles/360019349734-Install-Drift-on-a-Turbolinks-site They look for a <div id="drift-widget-container" data-turbolinks-permanent></div> element on the page and insert everything inside there if it's present.

Could we add a <div id="stripe-elements-container" data-turbolinks-permanent></div> element?

It would be great if Stripe could also handle the turbolinks:load event automatically. (Intercom also has built-in support for this event.)

rezmag-wontok commented 4 years ago

I am seeing this consistently starting yesterday when using this in our index.html angular page

<script src="https://js.stripe.com/v3/"></script>

That is how you add stripe to an Angular app :)

sboudouk commented 4 years ago

Same issue here for React, on Cordova on iOS.

vlad-at-work commented 4 years ago

Don't know if this helps anybody but I saw this error when trying to use a test card number (4242...) with live API key.

adamreisnz commented 4 years ago

FWIW we are getting the same error for the past year or so already in an Angular app. Loading the script directly via script tags. Seems random as well, so definitely not react specific.

Simonl9l commented 4 years ago

Seeing this as of today on a development environment...no clue on how to resolve. This is on initial page load (in Blazor app) with <script src="https://js.stripe.com/v3/"></script>

The browser console window shows this:

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://js.stripe.com') does not match the recipient window's origin ('http://localhost:5060').
vn @ :formatted:1228
value @ :formatted:1533
value @ :formatted:1499
value @ :formatted:2447
value @ :formatted:2431
n @ :formatted:2466
rezmag-wontok commented 4 years ago

@Simonl9l sounds like a CORS issue but also looks like a matter of calling a https endpoint whereas your site is hosted over http. I see quite a few conversations on the net about this similar issue. Dig deeper ;)

Simonl9l commented 4 years ago

Actually we can thank Chromium Edge in this case (v84.0.522.49) on MacOS.

@rezmag-wontok Thanks for the reply - This was not as agreeably perceived to be a CORS issue, Nothing had changed in the development environment, related in any way to over over 100's of recent successful tests since last changes in our code in this area from over a week ago or the runtime environment.

On restart of the browser the issue went away...albeit the cause of why this broke is unknown. Only that this won't make for a good user/future customer experience should the happen in a production environment on said users browsers, resulting in a revenue impact for us.

It would be good to understand from a Stripe perspective how they might recommend we'd be able to guard agains such issues arising from deep within with the stripe.js script.

friksa commented 4 years ago

It comes and goes without making any changes on our side. Tell us how to fix this random behavior because we have done everything in your documentation and we are not alone when it comes to this issue. How developer focused is Stripe nowadays?

hofman-stripe commented 4 years ago

We haven't been able to reproduce this issue, so it's hard to tell what's going on. I'll take an educated guess at the possible cause:

Stripe.js uses iframes to securily collect sensitive PCI data. To make sure this data does leak to untrusted frames, when data is exchanged between iframes, or sent from the top frame to a Stripe iframe, the origin option of postMessage is used. Iframes are referenced and looked up by the name registration mechanism of browsers, aka window.frames[name].

There shouldn't be any place where we try to send a message to a frame before we know it has loaded. There may be cases where the frame gets reloaded outside of our control (we've seen some browser extension interacting negatively). In those cases, it's possible we try to send a message to a mounted frame that, since it hasn't loaded, doesn't have the correct origin (before the first load, the default "about:blank" page has the same origin as the parent, aka your site).

Another cause could be a react re-render that removes and re-inserts the Element, and thus the iframe, in the DOM tree.

Normally these shouldn't cause any lasting issue, and when the frame gets loaded again, it we be re-initialized. Where I'm surprise is that some of you mention the Element is never rendered after that.

For anyone experiencing this problem, having a capture of the network requests would be valuable. Any iframe reloading "should" show up in there.

friksa commented 4 years ago

We use it as part of Angular... or I should say used. When this error message occurs, nothing Stripe works for us... so we removed it for now and looking at alternatives

hofman-stripe commented 4 years ago

We have a lot of successful integrations with Angular, and obviously React, so there must be some kind of trigger. Also dev tools have features such as dynamic partial reload that often interact with the page in unexpected ways (e.g. removing our iframe from the DOM, while keeping the JavaScript that expects the presence of the iframe). If there are reproducible issues in a production build, in a clean browsing profile (no extensions), I'd love to take a look at them.

friksa commented 4 years ago

We see these issues in production. Will enable stripe again and get you a network capture when it happens again. What capture filter should I use?

hofman-stripe commented 4 years ago

The best would be consistent reproduction steps, or at least semi-consistent. If the issue reproduces in Chrome, the network tab can "Export HAR". Unfortunately browsers do not capture network activity before the dev tools are open. Having a capture of the console (with timing) would be good too.

Simonl9l commented 4 years ago

@friksa our shared concern seem be that we need to do what ever we can so that future customers don't see these issues in production, and hope that Stripe understand that this becomes a trust imperative for committing to use their product for the value proposition it offers.

@hofman-stripe We're using Blazor, and since this is a technology set that is gaining increased usage and support from a Net Core perspective, we sincerely hope that Strip is taking this tooling direction seriously.

Blazor is a generally a SPA Reactive environment dynamically rendering the DOM in memory on the server side with each user session maintained in a Signal/R connection circuit. All user input is sent tot he's server and resultant DOM changes are streamed the browser to render as deltas a result of rendering each Page or Component on the server. We are not currently using Web Assembly browser rendering.

It seems given that Stripe.js initiates another iframe, per the docs this creates it own circuit with the Blazor server.

We have added JS code to destroy the DOM mount after a given payment/setup intent is completed so as to remove any DOM dependancies, such that if a user navigates away and back to a "purchase" page the Stripe Elements get rendered correctly.

It would be good to understand if there are any underlying issues here we are not aware of based on the Stripe.js implementation, and its supported usage inside a Blazor environment, such that any Blazor integration approaches/requirements are properly documented.

Whist we have something working today, from a development perspective, making this "live" is not far away, We fear a bad future customer experience, and hope that Stripe would be fully engaged if we detect this impact in "live" billing mode very seriously at that point...

friksa commented 4 years ago

It's almost 3 years since the issue first was reported. The best way to lose a customer is when you are not able to take their money when they are ready to give it to you. I hope they finally get serious about this critical issue or they will lose our business just as fast.

Simonl9l commented 4 years ago

@friksa agreed, however our reproducibility of what is essentially a random issue should not just be on us.

@hofman-stripe - If Strip (per your comments above) have a conceptual understanding as to what is going on here, perhaps a mechanism is needed (defensive coding - assumptions are bad) in the stripe js implementation to better handle this?

If this is then documented such that we as Stripe's customers would know in our implementations that the underlying JS magic is having an issue (like the iframe is not loaded properly).

We can then hopefully, have the mechanisms to better handle the issue more cleanly within our overall customer experience so we don't lose said new customer.

The mechanisms with some best practice documentation of what we'd need to do in this example context to ensure the iframe is properly rendered would also very helpful.

asolove-stripe commented 4 years ago

Hi all,

This problem sounds very painful and I want to apologize that it's so hard to figure out. I am committed to helping, but it's very hard to make progress without having a way to see the problem happen.

Does anyone have a public URL or open-source repo where this problem occurs, even just sometimes? (Or a private URL that I can reach for a little while to do some debugging?) Would especially love a Turbolinks or Blazor example that we can play with.

If you have something private, you can email me at asolove@stripe.com. We'll definitely debug and figure out what's going on and whether there's a way for Stripe to fix on our side or if there is an underlying incompatibility with the technology that we need to solve at the Turbolinks or Blazor level.

Thank!

friksa commented 4 years ago

@Simonl9l I wish our customers would agree with that logic... Thanks for reopening it and be clear how we can help you resolve this. That was lacking before. Please be patient as it sometimes work for a while before the problem randomly appears out of nowhere.

Simonl9l commented 4 years ago

@asolove-stripe Thanks so much for reopening this issue. The apologies are not needed, on the basis that "we" (with Stripe's help and self drive) can get to some end of resolution to establish how to better guard against this issue and the potential resultant bad "lost new customer" experience.

These scenarios also hits Stripe's bottom line in the grand scheme of things. From our perspective as Stripe customers, we're paying 2.9% of revenue to get to a resolution here. We loose 100% for lost new customers and their future revenues. Stripe loses 2.9% of each failed new customer experience, and that's 2.9% future revenue stream too - it all adds up!

My point here is that this should not require us as customers to have to hunt for ways to reproduce this, such that it is dependent on the stripe.js implementation.

One only hope that Stripe has a mechanism to detect these issues and instrument their occurrences to the back-end so there is at least some transparency to the scope and impact of this lost business - given projected multi-year growing losses on lost multi-year subscriptions for example.

I ran into this having been continuously testing with a single Edge browser window/tab for days, just refreshing to create a new Blazor circuit and continuing testing, and for no apparent reason it started to blow up. Restarting the Edge browser eliminated the underlying error condition, so assume is related to perhaps cookies or local storage maintained by the iframe that was not air apparent. I feel very sorry for Stipe customers such as @friksa that are losing real customers due to this issue not being resolved. A very sad state of affairs.

In terms of Blazor samples (or any other error scenarios - I'd be committed as Stripe learn that underlying tech to understand potential issue scenarios) - I'd just:

  1. set up a blazer server template/sample dotnet new blazorserver
  2. add a requisite JavaScript file in your wwwroot/assets/js folder to setup the Stripe Element.
  3. reference the stripe.js and Javascript file above in the _Host.cshtml file
  4. on a given razor page (or it's C# backing file) use the Stripe NuGet .Net package to set up the Payment/SetupIntent
  5. invoke s JsRuntime.InvokeVoidAsync call to invoke the JavaScript functionality above.

Having the Stripe Dev team do this might be insightful such that it will help with the future buildout of some Blazor integration documentation we can all learn from to go along side the React documentation?

However I have no idea what is needed to recreate this issue; but assume that:

  1. There are only so many ways the condition that causes this error can arise given the Stripe.js implementation?
    • Stripe knows this far better than us!
  2. Linking this up to a test harness that performs a refresh and other activity periodically over a few day and we can only hope the error condition arises...?
hofman-stripe commented 4 years ago

Quick technical note: Stripe.js does not have any kind of saved state or cookies. The only state resides in the JavaScript heap and the live DOM. The fact that a browser restart is necessary, and not just a tab closing, refresh or new full page navigation, points strongly to an issue with some kind of browser extension, or state saved somewhere else.

One probably relevant assumption our library makes is that the hidden iframe we insert in the body will not be removed by external code. We can probably be more defensive here, but at best it'll avoid console errors. It doesn't make sense to defend further against external interference with our internal execution state.

As for telemetry, it's probably one of those cases where we actually can't gather it. If our code is not able to run (because the iframe is not accessible), then we can't send back events either. Regardless, that kind of client side telemetry rarely translates cleanly to lost revenue.

I'm looking forward getting to the bottom of this.

Simonl9l commented 4 years ago

@hofman-stripe - Thanks for the update. TBH- I did not even try to just close the tab as I only had a single tab open - closing it, closed the browser. I'm using a new clean install of the new Chromium Edge browser with No extensions!

image

Our code does not use any local/session storage, it just establishes the standard Blazor Signal/R connection. It has a single cookie in support of an ApplicationInsights integration.

On review of the Application Storage, its seems that https://m.stripe.network seems to have some Session Storage

image
hofman-stripe commented 4 years ago

The cookies you mention is just for fraud detection and does not have any impact on execution.

It seems like Blazer (and Turbolinks) by their nature keep state shared across the client and server. When you mentioned a refresh earlier, was that a regular browser page refresh (maybe hard refresh for good measure), or some kind of Blazer specific refresh function? We'll investigate what exactly those frameworks do that could interfere with client side libraries like Stripe's.

Simonl9l commented 4 years ago

Best you take some time to understand Blazor. There is no client side state, it just receives DOM updates based on deltas with what is rendered over signal/R.

Navibhation in the app is like an SPA with each page/component (like React) causing DOM updates.

A (F9) hard refresh starts a new circuit with the server.

My issue arose on initial page load as a new Blazor circuit is created at that point only the stripe.js is included but no functions calls to JavaScrpt and Stripe Elements at that point.

At this point the console errors appear.

Layer when attempts are then made to set up the card with Stripe Elements nothing happens to refer the card input.

With out the developer console open you’d be otherwise unaware there was a prior issue.

guibovo commented 4 years ago

I'm facing the same issue and it seems to happen after payment if I refresh the page (or get away from it and then come back) my payment form does not appear. If I do a hard refresh (ctrl + f5) it appears again. I'm new to the company I'm currently working on, but I've seen that we use turbolink.

P.S. I've come to this page by accident, we don't use react in this application, but it seems like it is an issue from Stripejs API

P.S. 2 Apparently this issue does not occur if I place my script in a separated js file

sashko-stripe commented 3 years ago

Hi everyone, thanks for the discussion here. As of a few months ago, I'm the engineering manager responsible for this area at Stripe.

Sounds like we haven't yet achieved a reproduction here, and there also may be a few separate issues going on with different frameworks - Blazor, Turbolinks, etc. There are a few things we could do here, including getting a reproduction, identifying certain frameworks that aren't compatible with Elements, or documenting workarounds.

For now, I'm going to close this issue as the project has moved to the React Stripe.js repository. If you'd like to re-open the discussion, please create a new issue there. Please feel free to email me at sashko@stripe.com if you have any concerns about this.