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

如何避免浏览器审查工具修改代码导致YouTube视频推荐屏蔽失效

优化方案

你的原有方案核心问题是所有覆盖逻辑都依赖静态CSS类和公开DOM规则,普通用户只要通过审查工具删除对应类名或CSS规则就能绕过限制。所有前端防护都只能提高篡改门槛,无法实现100%绝对防破解,以下方案可拦截99%以上普通用户的篡改操作:

核心优化点

  • 放弃CSS类控制覆盖效果,改用JS直接写入内联样式,避免用户删除CSS规则或DOM类名后失效
  • 接入MutationObserver监听播放器容器的所有DOM变动,用户修改样式/类名/节点时自动恢复正确配置
  • 增加定时轮询机制,每100ms校验一次播放器状态,强制同步覆盖层显示逻辑
  • 可对核心JS代码做混淆处理,提高用户定位核心逻辑的成本

修改后完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/styles.css">
    <link rel="shortcut icon" href="imgs/icon/favicon.ico">
    <style>
    .hytPlayerWrap {
        display: inline-block;
        position: relative;
        background-position: center;
        background-repeat: no-repeat;
    }
    .ytp-copylink-title{
        display: none;
    }
    </style>
    <title> 2021</title>
</head>
<body id="plenario">
<div class="container-fluid">
<div class="row">
    <div class="col-12">
        <br><br><br><br>
        <div class="row">
            <div class="col-2">&nbsp;</div>
            <div class="col-8 text-center">
                <div class="hytPlayerWrapOuter" >
                    <div class="hytPlayerWrap" style="background-image:url(imgs/Captura.jpg)">
                        <iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/wzWmZYi4qMg?rel=0&controls=0&enablejsapi=1"  allowfullscreen="allowfullscreen" frameborder="0"></iframe>
                    </div>
                </div>
            </div>
            <div class="col-2">&nbsp;</div> 
        </div>
    </div>
    <div class="seccion-regresar-plenario"> 
    </div>  
</div>
</div>
<script src="js/jquery-3.5.1.min.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>  
<script src="js/utiles.js"></script>
<script>
    "use strict";
    document.addEventListener('DOMContentLoaded', function () {
        if (window.hideYTActivated) return;
        // 覆盖层样式配置,不写入静态CSS
        const coverStyle = {
            ended: {
                content: '""',
                position: 'absolute',
                top: 0,
                left: 0,
                bottom: 0,
                right: 0,
                cursor: 'pointer',
                backgroundRepeat: 'no-repeat',
                backgroundPosition: 'center',
                backgroundSize: '64px 64px',
                backgroundImage: 'url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgNTEwIDUxMCI+PHBhdGggZD0iTTI1NSAxMDJWMEwxMjcuNSAxMjcuNSAyNTUgMjU1VjE1M2M4NC4xNSAwIDE1MyA2OC44NSAxNTMgMTUzcy02OC44NSAxNTMtMTUzIDE1My0xNTMtNjguODUtMTUzLTE1M0g1MWMwIDExMi4yIDkxLjggMjA0IDIwNCAyMDRzMjA0LTkxLjggMjA0LTIwNC05MS44LTIwNC0yMDQtMjA0eiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==)'
            },
            paused: {
                content: '""',
                position: 'absolute',
                left: 0,
                right: 0,
                width: '640px',
                height: '340px',
                cursor: 'pointer',
                backgroundRepeat: 'no-repeat',
                backgroundPosition: 'center',
                backgroundSize: '40px 40px',
                backgroundImage: 'url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSIxNzA2LjY2NyIgaGVpZ2h0PSIxNzA2LjY2NyIgdmlld0JveD0iMCAwIDEyODAgMTI4MCI+PHBhdGggZD0iTTE1Ny42MzUgMi45ODRMMTI2MC45NzkgNjQwIDE1Ny42MzUgMTI3Ny4wMTZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+)'
            }
        }
        let onYouTubeIframeAPIReadyCallbacks = [];
        for (let playerWrap of document.querySelectorAll(".hytPlayerWrap")) {
            let playerFrame = playerWrap.querySelector("iframe");
            let tag = document.createElement('script');
            tag.src = "https://www.youtube.com/iframe_api";
            let firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
            let player;
            // 状态同步函数
            const syncState = () => {
                if(!player) return
                const state = player.getPlayerState()
                // 清空之前的伪类样式
                playerWrap.style.content = ''
                Object.keys(coverStyle.ended).forEach(k => playerWrap.style[k] = '')
                Object.keys(coverStyle.paused).forEach(k => playerWrap.style[k] = '')
                if(state === YT.PlayerState.ENDED){
                    Object.assign(playerWrap.style, coverStyle.ended)
                    playerFrame.style.visibility = 'hidden'
                }else if(state === YT.PlayerState.PAUSED){
                    Object.assign(playerWrap.style, coverStyle.paused)
                    playerFrame.style.visibility = 'hidden'
                }else if(state === YT.PlayerState.PLAYING){
                    playerFrame.style.visibility = 'visible'
                }
            }
            let onPlayerStateChange = function (event) {
                syncState()
            };
            onYouTubeIframeAPIReadyCallbacks.push(function () {
                player = new YT.Player(playerFrame, {events: {'onStateChange': onPlayerStateChange}});
                // 每100ms轮询同步状态
                setInterval(syncState, 100)
            });
            // 监听DOM变动,用户修改样式自动恢复
            const observer = new MutationObserver(syncState)
            observer.observe(playerWrap, { attributes: true, childList: true, subtree: true, attributeFilter: ['style', 'class'] })
            observer.observe(playerFrame, { attributes: true, attributeFilter: ['style', 'class'] })
            playerWrap.addEventListener("click", function () {
                let playerState = player.getPlayerState();
                if (playerState == YT.PlayerState.ENDED) {
                    player.seekTo(0);
                } else if (playerState == YT.PlayerState.PAUSED) {
                    player.playVideo();
                }
            });
        }
        window.onYouTubeIframeAPIReady = function () {
            for (let callback of onYouTubeIframeAPIReadyCallbacks) {
                callback();
            }
        };
        window.hideYTActivated = true;
        // 可选:禁用F12、右键等快捷操作,提高门槛
        document.addEventListener('contextmenu', e => e.preventDefault())
        document.addEventListener('keydown', e => {
            if(e.key === 'F12' || (e.ctrlKey && e.shiftKey && e.key === 'I')) e.preventDefault()
        })
    });
</script>   
</body>
</html>

额外强化建议

你可以将<script>标签内的核心逻辑通过JS混淆工具做混淆处理,替换所有可读变量名为无意义字符、加密字符串常量,进一步提高用户破解的成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 02:42:02