You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueJS开发的Google Pay在移动端Edge/Firefox无法使用求助

Google Pay在移动端Edge/Firefox跨域帧访问错误解决方案

问题核心原因

错误栈显示Vue的响应式系统在尝试遍历Google Pay iframe返回的对象属性时,触发了浏览器的跨域帧访问限制。移动端Edge和Firefox对跨域iframe的属性访问策略比桌面端及移动端Chrome更严格,导致hasOwnProperty调用被拦截,进而阻塞Google Pay弹窗加载。

解决方案

1. 避免将Google Pay实例纳入Vue响应式系统

不要把Google Pay的PaymentsClient实例或弹窗相关对象赋值给Vue组件的data(Vue2)、ref/reactive(Vue3),这些API会让Vue对对象进行响应式代理,遍历属性时触发跨域检查。

正确做法:
将实例存储为组件的普通属性,而非响应式属性:

// Vue 2
export default {
  mounted() {
    // 不要放在data里,直接存在组件实例的普通属性中
    this.$googlePayClient = new google.payments.api.PaymentsClient({
      environment: 'TEST',
      merchantInfo: { merchantId: 'your-merchant-id' }
    });
  },
  methods: {
    async showGooglePay() {
      const paymentDataRequest = {/* 你的请求配置 */};
      await this.$googlePayClient.loadPaymentData(paymentDataRequest);
      // 处理支付数据
    }
  }
}

// Vue 3
import { onMounted } from 'vue';

export default {
  setup() {
    // 用普通变量存储,而非ref/reactive
    let googlePayClient = null;

    onMounted(() => {
      googlePayClient = new google.payments.api.PaymentsClient({
        environment: 'TEST',
        merchantInfo: { merchantId: 'your-merchant-id' }
      });
    });

    const showGooglePay = async () => {
      const paymentDataRequest = {/* 你的请求配置 */};
      await googlePayClient.loadPaymentData(paymentDataRequest);
      // 处理支付数据
    };

    return { showGooglePay };
  }
}

2. 冻结Google Pay对象,阻止响应式代理

如果必须将对象关联到组件实例,使用Object.freeze冻结对象,避免Vue对其进行响应式处理:

mounted() {
  const client = new google.payments.api.PaymentsClient({...});
  // 冻结后Vue不会对其进行响应式观察
  this.googlePayClient = Object.freeze(client);
}

3. 隔离Google Pay方法的执行上下文

调用Google Pay的show或loadPaymentData方法时,确保不会让Vue的响应式系统追踪到内部对象的变化。可以将相关逻辑封装在独立函数中,避免使用组件实例的响应式属性作为中间变量:

async showGooglePay() {
  // 直接创建实例或使用非响应式存储的实例
  const client = new google.payments.api.PaymentsClient({...});
  const paymentDataRequest = {/* 配置 */};
  try {
    const paymentData = await client.loadPaymentData(paymentDataRequest);
    // 处理支付结果
  } catch (err) {
    console.error('Google Pay加载失败:', err);
  }
}

4. 验证SDK加载方式

确保Google Pay SDK通过官方异步方式加载,避免同步加载或通过Vue的响应式钩子触发异常加载:

async mounted() {
  await new Promise((resolve) => {
    if (window.google?.payments?.api) {
      resolve();
      return;
    }
    const script = document.createElement('script');
    script.src = 'https://pay.google.com/gp/p/js/pay.js';
    script.onload = resolve;
    document.body.appendChild(script);
  });
  // 初始化Google Pay客户端
  this.$googlePayClient = new google.payments.api.PaymentsClient({...});
}

验证方案

修改后在移动端Edge和Firefox测试:

  • 点击Google Pay按钮,检查弹窗是否正常加载
  • 查看控制台是否再出现跨域帧访问错误

内容的提问来源于stack exchange,提问作者GVR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:05:13