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

Codeigniter邮件营销工具:网站停留时间追踪unload事件触发异常求助

解决CodeIgniter邮件营销工具中unload事件请求不稳定的问题

我之前在做用户行为追踪的项目时,也碰到过unload事件发起请求经常失败的情况,结合你邮件营销工具的场景,给你几个经过实践验证的解决方案:

1. 优先使用navigator.sendBeacon()替代普通Ajax

浏览器在触发unload事件时,会快速释放页面资源,普通的XMLHttpRequest或fetch请求很容易被直接丢弃。而sendBeacon是浏览器专门为页面卸载时发送数据设计的API,它会异步发送请求但保证浏览器完成数据传输,不会阻塞页面卸载。

前端代码示例:

// 监听beforeunload事件(比unload更可靠)
window.addEventListener('beforeunload', function(event) {
    // 从Cookie中获取追踪数据
    const trackIp = getCookie('track_ip');
    const trackUrl = getCookie('track_url');

    if (trackIp && trackUrl) {
        // 构造FormData,sendBeacon支持FormData/Blob类型数据
        const formData = new FormData();
        formData.append('ip', trackIp);
        formData.append('url', trackUrl);

        // 发送到CodeIgniter的追踪更新接口
        navigator.sendBeacon('/tracking/update_closed_datetime', formData);
    }
});

// 辅助函数:获取指定Cookie
function getCookie(name) {
    const cookieStr = `; ${document.cookie}`;
    const cookieParts = cookieStr.split(`; ${name}=`);
    if (cookieParts.length === 2) {
        return cookieParts.pop().split(';').shift();
    }
    return null;
}

CodeIgniter后端控制器示例:

class Tracking extends CI_Controller {
    public function update_closed_datetime() {
        // 验证请求来源(可选,防止恶意请求)
        if (!$this->input->is_ajax_request()) {
            exit('Invalid request');
        }

        $ip = $this->input->post('ip');
        $url = $this->input->post('url');

        if ($ip && $url) {
            // 更新数据库中的closed_datetime
            $this->db->where([
                'ip' => $ip,
                'url' => $url
            ])->update('newsletter_tracking', [
                'closed_datetime' => date('Y-m-d H:i:s')
            ]);
        }
    }
}

2. 搭配页面可见性API补充追踪

用户切换标签页、最小化窗口等行为,虽然没有关闭页面,但也属于“结束浏览”的场景,可以监听visibilitychange事件作为补充,进一步提升数据准确性:

document.addEventListener('visibilitychange', function() {
    if (document.visibilityState === 'hidden') {
        const trackIp = getCookie('track_ip');
        const trackUrl = getCookie('track_url');
        
        if (trackIp && trackUrl) {
            const formData = new FormData();
            formData.append('ip', trackIp);
            formData.append('url', trackUrl);
            navigator.sendBeacon('/tracking/update_closed_datetime', formData);
        }
    }
});

3. 优化Cookie存储逻辑

确保Cookie能在整个官网域名下被读取,设置Cookie时指定path=/:

// 存储追踪数据到Cookie时的示例代码
document.cookie = `track_ip=${userIp}; path=/; max-age=3600`;
document.cookie = `track_url=${encodeURIComponent(newsletterUrl)}; path=/; max-age=3600`;

同时注意URL的编码一致性,前端存储时用encodeURIComponent处理,后端直接匹配编码后的字符串,避免因特殊字符导致数据库匹配失败。

4. 备选方案:同步请求(不推荐,仅作兜底)

如果需要兼容非常老旧的浏览器(不支持sendBeacon),可以使用同步XMLHttpRequest,但会阻塞页面卸载,影响用户体验,仅作为最后兜底:

window.addEventListener('unload', function(event) {
    const trackIp = getCookie('track_ip');
    const trackUrl = getCookie('track_url');
    
    if (trackIp && trackUrl) {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/tracking/update_closed_datetime', false); // 同步请求
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send(`ip=${encodeURIComponent(trackIp)}&url=${encodeURIComponent(trackUrl)}`);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:20:09