如何通过GTM跟踪无URL变更、无法注入JS的iframe嵌入Qgiv捐赠表单提交事件
如何通过GTM跟踪无URL变更、无法注入JS的iframe嵌入Qgiv捐赠表单提交事件
遇到这种跨域iframe且无法注入自定义代码的情况确实棘手,不过我们可以尝试以下几种方案,按实现难度从低到高排序:
方案1:监听iframe高度变化触发事件
Qgiv表单提交后切换到感谢页时,iframe的高度大概率会发生明显变化(你提供的初始高度是1444.4px,感谢页的高度通常会和表单页有差异)。我们可以在父页面通过GTM添加脚本,监听这个高度变化来触发提交事件。
具体步骤:
- 在GTM中创建一个自定义HTML标签,插入以下脚本:
(function() { // 定位到Qgiv的iframe const qgivIframe = document.getElementById('qgiv-embed'); if (!qgivIframe) return; // 记录初始高度 let lastHeight = qgivIframe.offsetHeight; // 高度变化阈值(可根据实际测试调整) const heightThreshold = 200; // 创建MutationObserver监听iframe的style属性变化 const heightObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.attributeName === 'style') { const currentHeight = qgivIframe.offsetHeight; // 当高度变化超过阈值时,判断为提交完成 if (Math.abs(currentHeight - lastHeight) > heightThreshold) { // 向GTM发送自定义事件 window.dataLayer.push({ 'event': 'qgiv_donation_success', 'event_category': '捐赠表单', 'event_action': '提交完成', 'event_label': 'Qgiv嵌入表单' }); // 仅触发一次,避免重复上报 heightObserver.disconnect(); } lastHeight = currentHeight; } }); }); // 启动监听 heightObserver.observe(qgivIframe, { attributes: true, attributeFilter: ['style'] }); })();
- 给这个标签设置触发条件:选择DOM Ready或Window Loaded,确保iframe已加载后再执行脚本。
- 新建一个自定义事件触发器,事件名称填写
qgiv_donation_success,用来触发你的GA4转化标签或其他统计标签。
⚠️ 注意:如果感谢页和表单页高度差异极小,需要调整heightThreshold的数值,或通过测试确认高度变化的范围。
方案2:利用Qgiv Webhook结合后端转发(最可靠)
如果高度监听的方法不稳定,最靠谱的方案是使用Qgiv自带的Webhook功能,结合自己的后端服务来同步捐赠事件到GTM。
具体步骤:
- 配置Qgiv Webhook:
登录Qgiv后台,在「设置/集成」栏目找到Webhook配置,新建一个Webhook,触发条件选择「捐赠完成(Donation Completed)」,设置接收URL为你自己的后端接口(比如https://你的域名.com/qgiv-webhook)。 - 后端处理Webhook:
在你的后端接口中,先验证Qgiv的Webhook签名(确保请求来自官方),然后可以选择两种方式同步事件:- 方式一:使用Server-Side GTM:直接在后端将Webhook的捐赠数据转化为GA4事件,通过Server-Side GTM发送到谷歌统计。
- 方式二:前端轮询:在后端存储捐赠的会话标识,然后在父页面通过GTM添加定期轮询脚本,向后端查询当前会话是否有完成的捐赠,若有则发送GTM事件。
- GTM接收事件:
对应后端的处理方式,在GTM中配置对应的触发器和标签,完成事件统计。
方案3:尝试跟踪表单提交的网络请求(局限性大)
虽然跨域限制会阻止父页面直接监听iframe的网络请求,但可以尝试通过脚本覆盖fetch或XMLHttpRequest来捕获可能的捐赠提交请求。不过这个方法仅当请求是从父页面上下文发起时才有效(Qgiv表单大概率不会这样,但可以快速测试)。
具体步骤:
在GTM中创建自定义HTML标签,插入以下脚本:
(function() { // 监听fetch请求 const originalFetch = window.fetch; window.fetch = function(resource, options) { const result = originalFetch.apply(this, arguments); // 替换为Qgiv捐赠提交的API URL特征 if (typeof resource === 'string' && resource.includes('qgiv.com/api/donations')) { result.then(res => { if (res.ok) { window.dataLayer.push({ 'event': 'qgiv_donation_success', 'event_category': '捐赠表单', 'event_action': '提交完成', 'event_label': 'Qgiv嵌入表单' }); } }); } return result; }; // 监听XMLHttpRequest请求 const originalXHR = window.XMLHttpRequest; window.XMLHttpRequest = function() { const xhr = new originalXHR(); const originalOpen = xhr.open; xhr.open = function(method, url) { this._requestUrl = url; originalOpen.apply(this, arguments); }; const originalOnLoad = xhr.onload; xhr.onload = function() { if (this._requestUrl.includes('qgiv.com/api/donations') && this.status === 200) { window.dataLayer.push({ 'event': 'qgiv_donation_success', 'event_category': '捐赠表单', 'event_action': '提交完成', 'event_label': 'Qgiv嵌入表单' }); } originalOnLoad?.apply(this, arguments); }; return xhr; }; })();
内容来源于stack exchange
相关产品推荐
相关产品推荐

