安全拦截跳转脚本

各个浏览器对网站的审查越来越严格了,外链多了容易降低网站信誉

php 复制代码
在这里插入代码片
```<?php /* EL PSY CONGROO */
$t_url = preg_replace('/^url=(.*)$/i','$1',$_SERVER["QUERY_STRING"]);
if(!empty($t_url)) {
    preg_match('/(http|https):\/\//',$t_url,$matches);
    if($matches){
        $url=$t_url;
        $title='页面跳转中...';
    } else {
        preg_match('/\./i',$t_url,$matche);
        if($matche){
            $url='http://'.$t_url;
            $title='页面跳转中...';
        } else {
            $url=$zbp->host;
            $title='参数错误,正在返回首页...';
        }
    }
} else {
    $title='参数缺失,正在返回首页...';
    $url=$zbp->host;
}
$url_json = json_encode($url);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title><?php echo $title;?></title>
<style>
body{background:#000;margin:0;height:100%}
.loading{-webkit-animation:fadein 2s;-moz-animation:fadein 2s;-o-animation:fadein 2s;animation:fadein 2s}
@-moz-keyframes fadein{from{opacity:0}to{opacity:1}}
@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}
@-o-keyframes fadein{from{opacity:0}to{opacity:1}}
@keyframes fadein{from{opacity:0}to{opacity:1}}
.spinner-wrapper{position:fixed;top:0;left:0;z-index:300;width:100%;height:100%;background:rgba(255,255,255,0.95)}
.spinner-text{position:absolute;top:50%;left:50%;margin-left:-100px;margin-top:50px;color:#888;letter-spacing:1px;font-weight:700;font-size:18px;font-family:Arial;width:200px;text-align:center}
.spinner{position:absolute;top:50%;left:50%;display:block;margin-left:-25px;margin-top:-50px;width:1px;height:1px;border:8px solid rgba(255,0,0,1);-webkit-border-radius:50px;-moz-border-radius:50px;border-radius:50px;border-left-color:transparent;border-right-color:transparent;-webkit-animation:spin 1.5s infinite;-moz-animation:spin 1.5s infinite;animation:spin 1.5s infinite}
@-webkit-keyframes spin{0%,100%{-webkit-transform:rotate(0deg) scale(1)}50%{-webkit-transform:rotate(720deg) scale(0.6)}}
@-moz-keyframes spin{0%,100%{-moz-transform:rotate(0deg) scale(1)}50%{-moz-transform:rotate(720deg) scale(0.6)}}
@-o-keyframes spin{0%,100%{-o-transform:rotate(0deg) scale(1)}50%{-o-transform:rotate(720deg) scale(0.6)}}
@keyframes spin{0%,100%{transform:rotate(0deg) scale(1)}50%{transform:rotate(720deg) scale(0.6)}}

/* 提示面板 */
.notice-panel{display:none;position:fixed;top:0;left:0;z-index:400;width:100%;height:100%;background:#f5f5f7;color:#333;font-family:Arial,"Microsoft YaHei",sans-serif;overflow-y:auto}
.notice-box{max-width:500px;margin:10vh auto 0;padding:30px 25px;text-align:center;background:#fff;border-radius:12px;box-shadow:0 4px 20px rgba(0,0,0,.08);border-top:6px solid #ff3b30}
.notice-box.warn{border-top-color:#ff9500}
.notice-box.unknown{border-top-color:#8e8e93}
.notice-box.disabled{border-top-color:#8e8e93}
.notice-icon{font-size:50px;line-height:1;margin-bottom:15px}
.notice-title{font-size:20px;font-weight:700;margin:0 0 12px;color:#111}
.notice-desc{font-size:15px;color:#555;line-height:1.6;margin:0 0 10px;word-break:break-all}
.notice-meta{font-size:12px;color:#999;margin:0 0 25px}
.notice-btns{display:block;text-align:center}
.notice-btn{display:inline-block;padding:10px 24px;border-radius:8px;font-size:15px;font-weight:600;cursor:pointer;border:none;text-decoration:none;transition:opacity .2s;margin:0 5px}
.notice-btn:hover{opacity:.85}
.btn-back{background:#e5e5ea;color:#333}
.btn-go{background:#007aff;color:#fff}
.btn-go.warn{background:#ff9500}
.btn-go.unknown{background:#8e8e93}
.btn-go.disabled{background:#d1d1d6;color:#888;cursor:not-allowed;pointer-events:none}

/* 响应式适配手机端 */
@media screen and (max-width: 600px) {
    .notice-box{margin:5vh 15px;padding:25px 20px}
    .notice-icon{font-size:40px}
    .notice-title{font-size:18px}
    .notice-desc{font-size:14px}
    .notice-btn{display:block;margin:10px auto;width:80%}
}
</style>
</head>
<body>
<div class="loading" id="loadingWrapper">
  <div class="spinner-wrapper">
    <span class="spinner"></span>
    <span class="spinner-text" id="loadingText">正在检测网站安全性...</span>
  </div>
</div>

<div class="notice-panel" id="noticePanel">
  <div class="notice-box" id="noticeBox">
    <div class="notice-icon" id="noticeIcon">⛔</div>
    <h2 class="notice-title" id="noticeTitle">目标站点存在风险</h2>
    <p class="notice-desc" id="noticeDesc"></p>
    <p class="notice-meta" id="noticeMeta"></p>
    <div class="notice-btns" id="noticeBtns">
      <a class="notice-btn btn-back" id="btnBack" href="javascript:history.back();">返回上一页</a>
      <a class="notice-btn btn-go" id="btnGo" href="#">仍要继续访问</a>
    </div>
  </div>
</div>

<script>
(function(){
    "use strict";
    var TARGET_URL = <?php echo $url_json; ?>;
    var API_BASE   = "//api.afmax.cn/so/safety/index.php";
    var CACHE_PREFIX = "dns_safety_";
    var CACHE_TTL     = 365 * 24 * 3600;
    var loadingText = document.getElementById('loadingText');

    function getDomain(u){
        try{
            var a = document.createElement('a');
            a.href = u;
            return a.hostname || '';
        }catch(e){ return ''; }
    }
    function nowSec(){ return Math.floor(Date.now()/1000); }
    function readCache(domain){
        try{
            var raw = localStorage.getItem(CACHE_PREFIX + domain);
            if(!raw) return null;
            var obj = JSON.parse(raw);
            if(!obj || !obj.ts || (nowSec() - obj.ts) > CACHE_TTL){
                localStorage.removeItem(CACHE_PREFIX + domain);
                return null;
            }
            return obj;
        }catch(e){ return null; }
    }
    function writeCache(domain, statusId, status, msg, hitAny){
        try{
            localStorage.setItem(CACHE_PREFIX + domain, JSON.stringify({
                ts: nowSec(),
                status_id: statusId,
                status: status,
                msg: msg,
                hit_any: !!hitAny,
                v: 3
            }));
        }catch(e){ }
    }
    function fetchJSON(url){
        return new Promise(function(resolve, reject){
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.timeout = 10000; // 10秒超时
            xhr.onreadystatechange = function(){
                if(xhr.readyState !== 4) return;
                if(xhr.status === 200){
                    try{ resolve(JSON.parse(xhr.responseText)); }
                    catch(e){ reject(e); }
                } else {
                    reject(new Error('HTTP ' + xhr.status));
                }
            };
            xhr.ontimeout = function(){ reject(new Error('timeout')); };
            xhr.onerror   = function(){ reject(new Error('network')); };
            xhr.send();
        });
    }

    function detect(domain){
        // 直接带时间戳请求,避免两次请求造成延迟
        var t = Math.floor(Date.now()/1000/60);
        return fetchJSON(API_BASE + '?j=' + encodeURIComponent(domain) + '&t=' + t);
    }

    function doRedirect(){
        loadingText.innerHTML = "检测通过,正在跳转...";
        window.location.replace(TARGET_URL);
    }

    function showNotice(statusId, status, msg, hitAny, domain){
        var box   = document.getElementById('noticeBox');
        var icon  = document.getElementById('noticeIcon');
        var title = document.getElementById('noticeTitle');
        var desc  = document.getElementById('noticeDesc');
        var meta  = document.getElementById('noticeMeta');
        var btnGo = document.getElementById('btnGo');

        box.className = 'notice-box';
        btnGo.className = 'notice-btn btn-go';
        btnGo.style.display = 'inline-block';

        if(statusId === 3){
            // 危险:禁止访问
            box.className = 'notice-box disabled';
            btnGo.className = 'notice-btn btn-go disabled';
            icon.innerHTML = '&#9940;'; // ⛔
            title.innerHTML = '禁止访问';
            desc.innerHTML = '该网站经过 <strong>AFMAX.CN</strong> 判定异常,可能存在安全风险,已被拦截。';
            btnGo.innerHTML = '禁止访问';
            btnGo.href = 'javascript:void(0);';
        } else if(statusId === 2){
            // 可疑:手动确认
            box.className = 'notice-box warn';
            btnGo.className += ' warn';
            icon.innerHTML = '&#9888;'; // ⚠️
            title.innerHTML = '目标站点存在异常';
            desc.innerHTML = msg || ('域名 ' + domain + ' 的检测结果为:' + status);
            btnGo.innerHTML = '仍要继续访问';
            btnGo.href = TARGET_URL;
            btnGo.setAttribute('rel', 'noopener noreferrer');
        } else { 
            // 未知/请求异常:手动确认
            box.className = 'notice-box unknown';
            btnGo.className += ' unknown';
            icon.innerHTML = '&#10067;'; // ❓
            title.innerHTML = '目标站点安全状态未知';
            desc.innerHTML = msg || '安全检测服务暂时不可用或请求超时,请谨慎访问。';
            btnGo.innerHTML = '仍要继续访问';
            btnGo.href = TARGET_URL;
            btnGo.setAttribute('rel', 'noopener noreferrer');
        }
        
        meta.innerHTML = '检测结果来自 AFMAX.CN DNS 安全检测 API · 命中威胁情报:' + (hitAny ? '是' : '否');
        document.getElementById('noticePanel').style.display = 'block';
        document.getElementById('loadingWrapper').style.display = 'none';
    }

    function handleResult(statusId, status, msg, hitAny, domain, fromCache){
        switch(statusId){
            case 1: // safe
                doRedirect();
                break;
            case 2: // suspicious
            case 3: // dangerous
            case 4: // unknown
            default:
                showNotice(statusId, status, msg, hitAny, domain);
                break;
        }
    }

    function main(){
        var domain = getDomain(TARGET_URL);
        if(!domain){
            doRedirect();
            return;
        }

        // 1. 读本地缓存,有缓存直接走缓存结果
        var cached = readCache(domain);
        if(cached){
            handleResult(cached.status_id, cached.status, cached.msg, cached.hit_any, domain, true);
            return;
        }

        // 2. 无缓存,直接发起带时间戳的网络请求
        loadingText.innerHTML = "正在检测网站安全性,请稍候...";
        detect(domain).then(function(data){
            var sid = 4, status = 'unknown', msg = '检测失败,状态未知', hitAny = false;
            if(data && !data.error){
                sid     = data.summary && data.summary.overall_status_id || data.overall_status_id || 4;
                status  = data.summary && data.summary.overall_status   || data.overall_status || 'unknown';
                msg     = data.summary && data.summary.overall_message  || ('总体评级:' + status);
                hitAny  = data.blacklist && data.blacklist.hit_any || false;
                // 写入缓存
                writeCache(domain, sid, status, msg, hitAny);
            }
            // 请求完成,根据结果执行跳转或显示警告
            handleResult(sid, status, msg, hitAny, domain, false);
        }).catch(function(){
            // 任何非200响应或网络异常:降级为未知状态,让用户手动确认
            handleResult(4, 'unknown', '安全检测服务连接超时或失败,请确认网络状况。', false, domain, false);
        });
    }

    if(document.readyState === 'loading'){
        document.addEventListener('DOMContentLoaded', main);
    } else {
        main();
    }
})();
</script>
</body>
</html>