#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();
Кто-нибудь знает, почему это происходит, или, может быть, испытал что-то подобное и знает, как исправить / обойти это поведение?
Я был бы рад любой помощи.
Заранее благодарю вас.