网站被黑了最常见的现象是什么?不是首页被篡改,不是数据库被删,而是用户打开你的网站后被静默跳转到了赌博页、色情站、或者广告页。你自己打开是正常的,但搜索引擎的蜘蛛和普通用户打开就走到了别的地方。
这类JS跳转恶意代码有个特点:它藏得很深。不在HTML源码的显眼位置,而是嵌在某一个JS文件中间、伪装成正常的统计代码、甚至加密后再插入。如果是站群几十上百个站点,逐个打开看源码排查根本不现实。
JS恶意跳转的三种常见藏法
| 藏法一 | 直接植入script标签:在页面底部插入 <script>window.location.href='恶意网址';</script>,最粗暴但最容易被发现。 |
| 藏法二 | 污染公共JS文件:在jquery.min.js或common.js的末尾追加几行跳转代码,文件体积大、没有人会逐行审查。 |
| 藏法三 | 加密混淆后植入:跳转代码用eval+base64加密,写成 eval(atob('d2luZG93LmxvY2F0aW9u...')),人工肉眼完全看不出来。 |
JS跳转和HTTP跳转,检测方法完全不一样
很多人用HTTP状态码检测工具(查301/302)跑一遍网站,看到返回200就以为没问题。这是最容易忽略的盲区:
| 跳转类型 | 原理 | HTTP状态码 | 普通状态码工具能检测吗 |
|---|---|---|---|
| 服务器端301/302 | nginx/apache配置或htaccess规则 | 301或302 | ✅ 能 |
| HTML meta refresh | <meta http-equiv="refresh" content="0;url=..."> | 200 | ❌ 不能 |
| JavaScript跳转 | window.location / document.location / location.href | 200 | ❌ 不能 |
| iframe嵌套跳转 | 通过隐藏iframe加载恶意页面 | 200 | ❌ 不能 |
结论很明确:普通的状态码检测工具只能抓到HTTP层面的跳转,对JS跳转、meta refresh跳转、iframe跳转完全无能为力。而这些恰恰是恶意代码最常用的方式。

批量检测JS跳转,三种方案从简单到深入
方案一:在线工具做初步筛查
有几款在线工具可以做基础的JS跳转检测:
bfotool批量重定向检查器:支持批量输入URL,逐条检测HTTP状态码和跳转链。但它只检测HTTP层面的重定向,不解析JS。适合用来排查htaccess被篡改导致的跳转。
toolshu URL重定向分析工具:能追踪完整的跳转链路,显示每一跳的状态码和耗时。如果你怀疑某个页面在多次跳转后到达了恶意页面,用这个工具能看到完整的跳转路径。
在线工具的局限:这些工具都是模拟HTTP请求,不会执行JavaScript。所以它们只能发现"服务器端配置的跳转",发现不了"JS文件里藏着的跳转代码"。作为第一轮筛查可以,但不能当作最终结论。
方案二:Python脚本批量扫JS文件中的跳转关键词
要检测JS代码中的恶意跳转,核心思路是:遍历所有页面的源码,找出引用的JS文件,检查JS文件中是否包含跳转相关的关键词。这个方法不需要执行JS,速度快,适合批量扫描。

import requestsimport refrom urllib.parse import urljoin, urlparse# JS跳转特征关键词JS_REDIRECT_PATTERNS = [r'window\.location\s*[\.=]',r'document\.location\s*[\.=]',r'location\.href\s*=',r'location\.replace\s*\(',r'location\.assign\s*\(',r'eval\s*\(\s*atob\s*\(', # eval+base64加密r'eval\s*\(\s*function\s*\(', # eval+混淆函数r'fromCharCode\s*\(', # 字符编码混淆r'document\.write\s*\(\s*atob', # 动态写入加密内容r'\.src\s*=\s*[\'\"]http', # 动态加载外部脚本]def fetch_page(url):"""获取页面HTML"""try:resp = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})return resp.textexcept:return Nonedef extract_js_urls(html, base_url):"""从HTML中提取所有JS文件URL"""pattern = r'
