【问题标题】:iOS 13 Apple Pay button click throws error: "Must create a new ApplePaySession from a user gesture handler."iOS 13 Apple Pay 按钮单击引发错误:“必须从用户手势处理程序创建新的 ApplePaySession。”
【发布时间】:2020-02-03 03:42:27
【问题描述】:

在一个已经与 Apple Pay 集成了大约一年的网站上工作,现在没有任何问题。我们注意到,我们现在总是只在 iOS 13 设备上遇到错误。 iOS 12 及以下版本均按预期工作。

前端点击处理程序:

<div class="btn btn-apple">
  <div class="apple-pay-button apple-pay-button-white" lang="en" data-bind="click: intializeApplePaySession"></div>
</div>

JS 点击处理程序:

self.intializeApplePaySession = function() {
  new RestClient(RestClient.POST, "/rest/model/someController", {},
    //Success
    function(data, textStatus, jqXHR) {

      var session = new ApplePaySession(3,data.applePayPaymentRequest);
      initializeCallbacks(session);
      session.begin();
    },
...

“必须从用户手势处理程序创建一个新的 ApplePaySession。”总是抛出

var session = new ApplePaySession(3,data.applePayPaymentRequest);

适用于所有 iOS 13 设备。 iOS 12 及更低版本可以使用相同的代码正常工作。

从我的调试中我可以看到正在处理的事件是一个对我有意义的 MouseEvent。关于为什么抛出这个的任何想法?

【问题讨论】:

    标签: javascript ios knockout.js applepay


    【解决方案1】:

    我们正在逐步摆脱让网站在没有用户输入的情况下进行跨源调用。

    这已经被锁定了一段时间的一种方式是你不能触发,例如,一个表单的提交按钮......除非你从一个 click() 处理程序中执行它。因此,您可以在页面上放置一个闪亮的“立即购买”大图,然后通过单击该图片提交表单,但您不能只做 setTimeout(form.submit(), 100)

    我认为您在这里也遇到了同样的问题。 REST 调用在 click 处理程序中,但 apple pay 调用在 REST 调用的回调中,因此实际上不在 click() 处理程序中。

    当然,您正在使用 REST 调用来生成要传递给 Apple 的数据。您可能必须推测性地生成该数据。但在进行基础设施工作之前,我会试验一下您的点击处理程序的异步版本是否通过了他们的健全性检查。

    【讨论】:

    • 正确。查看该单击处理程序,您可能会在视图模型加载后立即初始化 RestClient(并保存它返回的数据),因为该处理程序似乎并没有将任何与购买相关的数据传递给 RestClient。那么现在成功回调中的代码将变为initializeApplePaySession
    • 感谢 Jason 和 Woodrow 兄弟,这实际上是有道理的。我绝对可以将 Rest 调用与 Apple Pay 会话的创建分离。我会试试这个。
    【解决方案2】:

    在与 Jason 和 Woodrow 兄弟讨论后工作 sn-p

    调用后端并获取当前购物车详细信息的同步函数。我们之前在成功回调中有这个的原因是因为我们使用的是 SPA 框架,所以购物车可以随时更改。当页面加载或数据可能过时时,我们不能调用它。

    self.getApplePayData = function() {
      var self = this;
      new RestClient(RestClient.POST, "/rest/model/getApplePayPaymentRequest", {},
        function(data, textStatus, jqXHR) {
          self.applePayData = data;
        },
    ....
    
     self.intializeApplePaySession = function() {
      var self = this;
      self.getApplePayData();
      var session = new ApplePaySession(3,self.applePayData.applePayPaymentRequest);
    

    我认为关键问题是我们在 rest 调用的成功回调中创建了一个新的 ApplePaySession,Apple 似乎不想再这样做了。

    【讨论】:

    • 你试过异步吗?还是您的浏览器基础不允许 ES6?
    【解决方案3】:

    来自官方文档的参考

    您尝试在用户手势之外创建 ApplePaySession 处理程序。异常错误“必须从 用户手势处理程序”出现。

    所以在你的情况下,你必须像这样创建一个苹果支付会话

    session = new window.ApplePaySession(version, request);
    

    然后向服务器创建请求并接收响应。

    const data = async getSomeCheckoutData();
    

    你可以继续付款扔苹果支付

    ...
    session.begin();
    

    主要思想是,首先,创建一个会话。然后你可以做请求并在它开始苹果支付会话之后。

    【讨论】:

    • 实际用作变量的最佳答案,如sessionrequest,都需要在点击处理程序方法本身中创建。
    【解决方案4】:

    您必须在类上方声明 ApplePayInstance 变量,以欺骗苹果支付会话,使其将其视为手势,也不要调用承诺

    http://baiduhix.blogspot.com/2018/06/must-create-new-applepaysession-from.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多