11
votes

I'm using Stripe Elements with vue-stripe-elements-plus on internal single page app. As there is no need to keep the stripe code running after user leaves change credit card module I want to unload Stripe completely but it doesn't appear to be that easy.

After I unload it in component's destroyed hook and remove added iframes:

destroyed () {
        this.$unloadScript('https://js.stripe.com/v3/');
        //delete window.Stripe; // commented because this makes stripe add iframes twice

        let stripeIframes = [
            document.querySelectorAll('[name^=__privateStripeMetricsController]'),
            document.querySelectorAll('[name^=__privateStripeController]'),
        ];

        stripeIframes.forEach(iframes => iframes.forEach(iframe => {
             iframe.parentNode.removeChild(iframe);
        }));
},

iframes which were added by Stripe:

enter image description here

are reappearing again after a while (one of them):

enter image description here

Seems like this iframe is recreated by Stripe's listeners which were attached to window object on message event. I'm unable to remove this listener because the handler function is located in an iframe which is inside iframe, so the browser won't let me access its internals.

Moreover, this listener is making unwanted requests to stripe:

XHR finished loading: POST "https://m.stripe.com/4".
2

2 Answers

0
votes

You can use setTimeout(destroyed, 1000)

0
votes

Instead of manually removing elements from DOM, you should use Stripe element's official destroy method. It should clear all Stripe listeners too.

With this lib, you can try something like this:

    <template>
     <div ref="card" />
    </template>
    
    <script>
    let stripe = window.Stripe('pk_test_xxxxxxxxxxxx'),
        elements = stripe.elements(),
        card = undefined;
    
    export default {
        name: 'Payment',
        mounted() {
          card = elements.create('card');
          card.mount(this.$refs.card);
        },
        beforeDestroy() {
          card.destroy(this.$refs.card);
        },
    }
    </script>