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

Chrome长时间运行出现net::ERR_HTTP2_PROTOCOL_ERROR及Ajax定时请求中断问题

问题分析与解决方案

问题现象

  • 页面循环播放短视频数小时,每60秒通过Ajax请求记录观看时长,运行数小时、数百次请求后随机出现错误:
    • Chrome:Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR(无指向对象)
    • Opera:GET '视频托管文件长URL' NET::ERR_CONNECTION_RESET 200
    • Chrome:指向Ajax JS文件的net::ERR_HTTP2_PROTOCOL_ERROR
  • 仅记录时长的Ajax请求中断,其他间隔≥60秒的日志请求及视频播放均正常。

可能原因排查

  1. HTTP/2连接复用限制
    浏览器会复用HTTP/2长连接发送请求,部分服务器、CDN或路由器对长连接的复用次数、闲置时长有阈值,超过后会强制断开连接。其他请求因路径/参数差异使用了不同连接池,未受影响。
  2. DDoS防护误拦截
    持续数小时的固定模式请求(相同路径、相似参数)可能被托管商的WAF/DDoS防护误判为自动化攻击,触发临时拦截。
  3. 前端请求逻辑缺陷
    当前代码仅在请求成功后才触发下一次请求,若单次请求失败可能导致连接资源未正常释放,积累后引发异常。
  4. 服务器资源泄漏
    后端MySQL连接、进程资源未正确释放,长时间运行后部分请求无法处理,但其他请求正常的话该可能性较低。

修复与优化建议

前端代码优化

添加失败重试机制与随机延迟,避免固定请求模式,防止单次失败中断流程:

// 更新日志时长
function updateVidTime() {
    const url = current_url;

    $.ajax({
        url: url,
        type: 'POST',
        data: {
            'updateTime': 1,
            'videoID': videoID,
            'visitID': visitID,
            'current_url': current_url,
            'timeSec': timeSec,
        },
        success: function(data) {
            const response = JSON.parse(data);
            timeSec = parseInt(response.timeSec) + waitTime;
            timerStarted = 0;
            // 添加1-3秒随机延迟,避免固定请求间隔
            const randomDelay = Math.floor(Math.random() * 3000);
            runVidTimer(timeSecMS + randomDelay);
        },
        error: function(xhr, status, error) {
            // 请求失败最多重试3次
            if (typeof this.retryCount === 'undefined') this.retryCount = 0;
            if (this.retryCount < 3) {
                this.retryCount++;
                setTimeout(() => updateVidTime(), 2000);
            } else {
                // 多次失败后重启定时器,避免流程中断
                runVidTimer(timeSecMS);
            }
        }
    });
}

function runVidTimer(delay = timeSecMS) {
    timerSetTmOut = setTimeout(updateVidTime, delay);
}

后端代码优化

修复SQL注入风险,确保资源正确释放:

if (isset($_POST['updateTime'])) {
    $videoID = $_POST['videoID'];
    $visitID = $_POST['visitID'];
    $current_url = $_POST['current_url'];
    $timeSec = $_POST['timeSec'];

    // 使用预处理语句防止SQL注入
    $sql = "UPDATE log SET timeSec = ? WHERE visitID = ? AND page = ?";
    $stmt = mysqli_prepare($conn, $sql);
    mysqli_stmt_bind_param($stmt, "sss", $timeSec, $visitID, $current_url);
    $result = mysqli_stmt_execute($stmt);
            
    if ($result) {
        $response = [
            'timeSec' => $timeSec
        ];
        echo json_encode($response);
        mysqli_stmt_close($stmt);
        exit();
    }
    // 处理执行失败场景
    echo json_encode(['error' => 'Update failed']);
    exit();
}

额外排查动作

  • 切换HTTP/1.1测试:前端Ajax添加xhrFields: {withCredentials: false},或服务器临时禁用HTTP/2,验证是否为HTTP/2协议层面问题。
  • 核查托管商防护日志:联系托管商确认该请求是否被WAF拦截,提供请求模式说明申请调整规则。
  • 更换网络环境测试:排除家用路由器、ISP的长连接超时限制问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:05:01