2016-03-28 3 views
14

Im используя Stripe Checkout.js для создания платежа. Я создаю обработчик, который в случае успеха отправляет маркер на сервер:Stripe - JSON Циркулярная ссылка

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. Он заканчивается успешно, то есть кнопка отображается зеленым цветом.

Но между моментом кнопка показывает зеленый цвет, и в тот момент, что маркер выводится на консоль (на обратный вызов обработчика), выдается ошибка:

EXCEPTION: TypeError: Converting circular structure to 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 на нем, что вызывает ошибку.

Эта ошибка не является фатальной, и оплата проходит, но знаете ли вы, что это может быть и как ее исправить?

Или существует известное обходное решение.

это full stack trace

Обратите внимание, что вызов stringify перед передачей объекта в postMessageможет не быть необходимым в соответствии с MDN docs.

postMessage использует механизм сериализации, который поддерживает круговые ссылки в соответствии с this.

+1

Итак, вы подставляете объект, имеющий ссылки на себя. Просто стройте его без этих ссылок. Что такое 'args'? – dfsq

+0

stringify - это код проверки полосы, а не код приложения. Я сообщил о проблеме Stripe, но разместил ее здесь, возможно, кто-то знает об обходном пути. Также, когда Angular 2 находится в бета-версии, вы никогда не знаете –

+1

Попробовали ли вы отладить этот фрагмент кода с помощью JSON.stringify? – dfsq

ответ

12

Проблема заключается в checkout.js (по линии 780 в де-уменьшенной файл):

message = JSON.stringify({ 
    method: method, 
    args: args, 
    id: id 
}); 

При работе в Angular2, zone.js обернул обратный вызов с информацией зоны. Это означает, что параметр арг выглядит следующим образом:

[5, ZoneTask]

И ZoneTask есть член, .zone, который содержит циклическую ссылку:

JSON.stringify(args[1].zone) 
> Uncaught TypeError: Converting circular structure to JSON(…) 

Таким образом, принципиально Stripe в checkout.js марок предположение о некруглости, которое больше не действует, когда Zone.js вмешивается. Полоса должна будет исправить это.

Тем временем вы можете использовать следующее: horrendous hack. Это так ужасно и так взломанно, что у меня глаза истекают кровью, но это лучшее, что я мог придумать, чтобы исправить это, не изменяя код Stripe. По сути, вы глобально замените JSON.stringify с версией, которая ломает любую зону -> _> zoneDelegate- циклы зоны в объекте его просят stringify:

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; 
    }); 
    } 
}; 

Извинения, если ваши глаза теперь кровотечение. Оно работает.

+1

Ваш хак работал как прелесть для меня. Я просто вложил его в ngOnInit в свой компонент оплаты, а также должен был проигнорировать «предоставленные параметры не соответствуют какой-либо сигнатуре ошибки вызова» из компилятора TypScript в строке «return _stringify ...». Большое спасибо! –

+3

Ошибка также может быть удалена добавлением перед JSON.stringify, когда оно назначено на const _stringify. –

+0

Эта ошибка была исправлена ​​в Stripe Checkout и должна работать только сейчас, нет необходимости в обходных решениях –

Смежные вопросы