Stripe - JSON Циркулярная ссылка
Я использую Stripe Checkout.js для создания платежа. Я создаю обработчик, который при успешном выполнении отправляет маркер на сервер:
let handler = StripeCheckout.configure({
key: 'my_key',
image: 'image.png',
locale: 'auto',
token: token => {
console.log(token.id);
// ... send token to server
}
});
Затем я использую обработчик для создания токена:
handler.open({
name: 'Test',
description: 'test',
billingAddress: false,
currency: 'eur',
amount: '1200',
});
Этот обработчик запускает всплывающее окно checkout.js, которое я заполняю и нажимаю Pay. Он заканчивается успешно, то есть кнопка отображается зеленым цветом.
Но между моментом, когда кнопка отображается зеленым цветом, и моментом, когда маркер печатается на консоли (при обратном вызове обработчика), возникает ошибка:
ИСКЛЮЧЕНИЕ: TypeError: преобразование круговой структуры в JSON
Основная часть stacktrace такова:
TypeError: Converting circular structure to JSON
at Object.stringify (native)
at Object.stringify (http://localhost:5000/dist/client/bundle.js:46294:29)
at RPC.sendMessage (https://checkout.stripe.com/checkout.js:1:18068)
at RPC.sendMessage (https://checkout.stripe.com/checkout.js:1:16180)
at https://checkout.stripe.com/checkout.js:1:17137
at RPC.ready (https://checkout.stripe.com/checkout.js:1:17416)
at RPC.invoke (https://checkout.stripe.com/checkout.js:1:17084)
at RPC.invoke (https://checkout.stripe.com/checkout.js:1:16180)
at RPC.processMessage (https://checkout.stripe.com/checkout.js:1:18899)
at RPC.processMessage (https://checkout.stripe.com/checkout.js:1:16180)
Проверяя код, мы видим, что проблема здесь:
RPC.prototype.sendMessage = function(method, args) {
var err, id, message, _ref;
if (args == null ) {
args = []
}
id = ++this.rpcID;
if (typeof args[args.length - 1] === "function") {
this.callbacks[id] = args.pop()
}
message = JSON.stringify({
method: method,
args: args,
id: id
});
Кажется, что Checkout.js создает объект сообщения, который имеет круговую ссылку, затем пытается вызвать JSON.stringify на нем, что вызывает ошибку.
Эта ошибка не является фатальной, и оплата идет, но знаете ли вы, что это может быть и как ее исправить?
Или существует известное обходное решение.
это полная трассировка стека
Обратите внимание, что вызов stringify
перед передачей объекта в postMessage
может не понадобиться в соответствии с документами MDN.
postMessage
использует механизм сериализации, который поддерживает циклические ссылки в соответствии с этим.
Ответы
Ответ 1
Проблема в checkout.js(в строке 780 в файле с уменьшенным размером):
message = JSON.stringify({
method: method,
args: args,
id: id
});
При работе в Angular2 zone.js завершает обратный вызов с информацией о зоне. Это означает, что параметр args выглядит следующим образом:
[5, ZoneTask]
И, ZoneTask имеет член,.zone, который содержит круговую ссылку: zone -> _zoneDelegate -> zone
JSON.stringify(args[1].zone)
> Uncaught TypeError: Converting circular structure to JSON(…)
Итак, принципиально Stripe checkout.js делает предположение о некруговой, которое больше не действует, когда Zone.js вмешивается. Stripe придется исправлять это.
Тем временем вы можете использовать следующий ужасный взлом. Это так ужасно и так взломанно, что у меня глаза кровоточат, но
это лучшее, что я мог придумать, чтобы исправить это, не изменяя код Stripe. По сути, вы глобально замените JSON.stringify версией, которая разбивает любые зоны → _ zoneDelegate- > зоны циклов в объекте, который его просят скрепить:
const _stringify = JSON.stringify;
JSON.stringify = function (value, ...args) {
if (args.length) {
return _stringify(value, ...args);
} else {
return _stringify(value, function (key, value) {
if (value && key === 'zone' && value['_zoneDelegate']
&& value['_zoneDelegate']['zone'] === value) {
return undefined;
}
return value;
});
}
};
Извините, если у вас теперь кровотечение. Он работает.