Действие возврата браузера не работает в Firefox, когда PayPal Plus iframe отображается на странице приложения react

#javascript #reactjs #firefox #paypal #paypal-plus

#javascript #reactjs #firefox #paypal #paypal-plus

Вопрос:

Я интегрировал iframe PayPal Plus в свое приложение react, добавив js-скрипт библиотеки PayPal в документ в componentDidMount, обновляя состояние компонента при загрузке скрипта, а затем вызывая метод библиотеки для инициализации объекта PayPal Plus. Это преобразует iframe в заполнитель div с соответствующим идентификатором. Я ознакомился с документацией (https://developer.paypal.com/docs/paypal-plus/germany/integrate/integrate-payment-wall /#) и внес вышеупомянутые изменения, чтобы использовать его в сочетании с моим приложением react.

Это работает до сих пор и выглядит так в минимализированном примере: страница с отображаемым iframe ppp

Однако в Firefox невозможно вернуться назад с помощью кнопки «Назад» браузера после инициализации iframe. Вместо этого весь компонент загружается внутри iframe. Вот так: страница после нажатия кнопки «Назад»

Этого не происходит в Chrome или Internet Explorer. Версия Firefox: 81.0 (64-разрядная версия)

Если я вручную удалю элемент iframe из DOM, кнопка возврата снова будет работать нормально. Я уже пытался использовать пользовательские обработчики событий для событий «popstate» и «beforeunload», чтобы попытаться обойти это, но безрезультатно. Эти события, по-видимому, не происходят в родительском окне в Firefox.

Шаги для воспроизведения:

  • Создайте приложение react (в примере я использовал версию 16.13.1) (https://reactjs.org/docs/create-a-new-react-app.html#create-react-app ).
  • Вставьте предоставленные классы в проект и используйте PppComponent в App.js .
  • Получите действительное одобрение песочницы PayPal и установите его в объекте конфигурации ppp.
  • Запустите yarn или запуск npm.
  • Откройте приложение в Mozilla Firefox и нажмите кнопку «Назад» в браузере.

По сути, это связанный код компонента:

 import React from 'react';
import utils from './utils';

class PppComponent extends React.Component {
    constructor() {
        super();
        this.state = {
            scriptLoaded: false
        }
    }

    componentDidMount() {
        utils.appendScript(
            'https://www.paypalobjects.com/webstatic/ppplus/ppplus.min.js',
            () => this.setState({scriptLoaded: true})
        );
    }

    componentWillUpdate(nextProps, nextState) {
        if (nextState.scriptLoaded) {
            this.initPaypalPlusIframe();
        }
    }

    componentWillUnmount() {
        utils.removeScript('https://www.paypalobjects.com/webstatic/ppplus/ppplus.min.js');
    }

    initPaypalPlusIframe() {
        const pppConfig = {
            approvalUrl: '{validApprovalUrl}',
            placeholder: 'ppplus',
            mode: 'sandbox',
            language: 'de_DE',
            country: 'DE',
            useraction: 'commit',
        };
        window.PAYPAL.apps.PPP(pppConfig);
    }

    render() {
        return (
            <div>
                <h1>Some Content Here</h1>
                <div id="ppplus"/>
            </div>
        );
    }
}

export default PppComponent;
  

И это функции util, используемые для добавления и удаления скрипта:

     class Utils {

    appendScript(scriptToAppend, onLoad) {
        const allSuspects = document.getElementsByTagName('script');
        let doAppend = true;
        if (allSuspects amp;amp; allSuspects.length > 0) {
            for (let i = allSuspects.length - 1; i >= 0; i--) {
                if (allSuspects[i] amp;amp; allSuspects[i].getAttribute('src') !== null
                    amp;amp; allSuspects[i].getAttribute('src').indexOf(`${scriptToAppend}`) !== -1) {
                    doAppend = false;
                }
            }
        }
    
        if (doAppend) {
            const script = document.createElement('script');
            script.src = scriptToAppend;
            script.async = false;
            script.onload = () => onLoad();
            document.body.appendChild(script);
        }
    }

    removeScript(scriptToRemove) {
        const allSuspects = document.getElementsByTagName('script');
        for (let i = allSuspects.length - 1; i >= 0; i--) {
            if (allSuspects[i] amp;amp; allSuspects[i].getAttribute('src') !== null
                amp;amp; allSuspects[i].getAttribute('src').indexOf(`${scriptToRemove}`) !== -1) {
                allSuspects[i].parentNode.removeChild(allSuspects[i]);
            }
        }
    }
}

export default new Utils();
  

Кто-нибудь знает, почему это происходит, или, может быть, испытал что-то подобное и знает, как исправить / обойти это поведение?

Я был бы рад любой помощи.

Заранее благодарю вас.