条纹-JSON循环参考 [英] Stripe - JSON Circular reference

查看:111
本文介绍了条纹-JSON循环参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Stripe Checkout.js创建付款.我正在创建一个处理程序,成功后将向服务器发送令牌:

Im using Stripe Checkout.js to create a payment. I'm creating a handler, that on success sends a token to the server:

let handler = StripeCheckout.configure({
                key: 'my_key',
                image: 'image.png',
                locale: 'auto',
                token: token => {

                    console.log(token.id);

                    // ... send token to server
                }
            });

然后我使用处理程序创建令牌:

Then I use the handler to create a token:

handler.open({
    name: 'Test',
    description: 'test',
    billingAddress: false,
    currency: 'eur',
    amount: '1200',
});

此处理程序触发我填写的测试checkout.js弹出窗口,然后单击付款".它成功结束,这意味着该按钮显示为绿色.

This handler triggers the test checkout.js popup, that I fill in and click Pay. It ends successfully, meaning the button displays green.

但是在按钮显示绿色的那一刻与将令牌打印到控制台的那一刻之间(在处理程序成功回调上)之间,会引发错误:

But between the moment the button shows green, and the moment that the token is printed to the console (on the handler success callback), an error is thrown:

例外:TypeError:将圆形结构转换为JSON

EXCEPTION: TypeError: Converting circular structure to JSON

stacktrace的主要部分是这样的:

The main part of the stacktrace is this:

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)

通过检查代码,我们发现问题出在这里:

By inspecting the code, we see the issue is here:

        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,这会导致错误.

It seems that Checkout.js creates a message object, that happens to have a circular reference, then it attempts to call JSON.stringify on it, which causes the error.

此错误不是致命错误,可以付款,但是您知道这可能是什么以及如何解决吗?

This error is non fatal and the payment goes through, but do you know what this could be and how to fix it?

或者是否存在已知的解决方法.

Or is there a known workaround.

这是完整堆栈跟踪

请注意,根据 postMessage使用一种串行化机制,该机制根据.

postMessage uses a serialization mechanism that supports circular references according to this.

推荐答案

问题出在checkout.js中(在缩小的文件中的第780行):

The problem is in checkout.js (at line 780 in the de-minified file):

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

在Angular2中运行时,zone.js已使用区域信息包装了回调.这意味着args参数如下所示:

When running in Angular2, zone.js has wrapped the callback with zone information. This means that the args parameter looks like:

[5, ZoneTask]

并且,ZoneTask具有成员.zone,该成员包含循环引用:zone -> _zoneDelegate -> zone

And, ZoneTask has a member, .zone, which contains a circular reference: zone -> _zoneDelegate -> zone

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

因此,从根本上来说,Stripe的checkout.js做出了一个非圆性假设,当Zone.js介入时,该假设不再有效.条纹将不得不解决此问题.

So, fundamentally Stripe's checkout.js makes a non-circularity assumption which is no longer valid when Zone.js has been meddling. Stripe are going to have to fix this.

同时,您可以使用以下可怕的 hack.太恐怖了,太笨拙了,使我的眼睛流血了,但是 这是我能提出的最好的解决方案,无需修改Stripe的代码.本质上,您将JSON.stringify全局替换为一个版本,该版本会破坏被要求进行字符串化的对象中的任何zone-> _ zoneDelegate-> zone周期:

In the meantime you can use the following horrendous hack. It's so horrendous and so hacky that it makes my eyes bleed, but it's the best I could come up with to fix it without modifying Stripe's code. Essentially, you globally replace JSON.stringify with a version that breaks any zone->_zoneDelegate->zone cycles in the object it is being asked to 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;
    });
  }
};  

很抱歉,如果您的眼睛现在流血.可以.

Apologies if your eyes are now bleeding. It works.

这篇关于条纹-JSON循环参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆