首页 微壳儿记 正文
一次网站跨域拦截排查实录:从 jQuery 加载失败到 www 域名跳转

一次网站跨域拦截排查实录:从 jQuery 加载失败到 www 域名跳转

一个看似简单的 $ is not defined 报错,背后藏着 ORB 安全机制、MIME 类型、CORS、域名不一致四个坑。记录完整排查过程,希望能帮到遇到类似问题的朋友。


一、问题的开始:满屏红色报错

今天打开自己的 EMLOG 博客,控制台一片红:

 
A resource is blocked by OpaqueResponseBlocking, please check browser console for details. jquery.min.3.5.1.js
指向"https://www.yangchao.net/js/jquery.min.3.5.1.js"的 <script> 加载失败。
Uncaught ReferenceError: $ is not defined
Uncaught ReferenceError: jQuery is not defined
 

页面上所有依赖 jQuery 的功能全挂了:日历、评论、侧边栏吸顶、图片缩放……一个都动不了。

第一反应是 jQuery 文件坏了?还是版本太旧?于是我先去查了 jQuery 的版本问题——结果发现,方向完全错了​。


二、第一个坑:以为更新 jQuery 就能解决

我一开始的想法很自然:既然报错是 jQuery 相关,那更新一下 jQuery 版本不就行了?

但仔细看报错信息才发现,浏览器说的是:

“A resource is blocked” —— 资源被拦截了。

也就是说,浏览器根本没让这个文件下载成功​,它压根没看到 jQuery 的内容。文件是新的还是旧的,浏览器不知道,也不关心。

关键结论​:只要服务器返回 JS 文件的方式不对,换什么版本的 jQuery 都会被拦截。问题不在文件内容,而在服务器发送文件的响应头​。


三、第二个坑:ORB 是什么?

报错里的 OpaqueResponseBlocking,简称 ORB​,是 Chrome 等现代浏览器的一项安全机制。

它的作用是:当浏览器请求一个跨域资源时,如果服务器返回的 Content-Type(MIME 类型)和资源实际类型对不上,浏览器就会直接拦截,防止潜在的安全风险。

举个例子:

  • 你请求的是 jquery.min.3.5.1.js
  • 服务器却返回 Content-Type: text/plain 或 text/html
  • 浏览器一看:“这不对啊,你说这是 JS,但标记是纯文本,可能是个伪装攻击”——拦截。

正常情况下,Nginx/Apache 会自动给 .js 文件返回 application/javascript,给 .css 返回 text/css。但如果配置有误,就会出问题。


四、第三个坑:真正的原因是域名不一致

继续排查,我注意到日志里两个地址:

  • 页面地址:https://yangchao.net/(​不带 www​)
  • 资源地址:https://www.yangchao.net/js/...(​带 www​)

在浏览器眼里,这两个是不同的源​。于是:

  1. 页面从 yangchao.net 加载
  2. 却要从 www.yangchao.net 加载 jQuery
  3. 跨域 + MIME 类型可能不对 → 触发 ORB 拦截
  4. jQuery 没加载成功 → $ is not defined
  5. 所有依赖 jQuery 的脚本连锁报错

根源找到了:EMLOG 后台的“站点地址”设置成了 https://yangchao.net,但部分页面/按钮仍然生成 www.yangchao.net 的链接。


五、排查过程:一步步定位

第一步:确认 ORB 拦截的具体资源

打开浏览器 F12 → Network,刷新页面,找到红色的失败请求,点进去看 Response Headers 里的 Content-Type。

第二步:检查 EMLOG 后台站点地址

登录 EMLOG 后台 → 设置 → 基本设置,确认“站点地址”填的是 https://yangchao.net(不带 www),和实际访问域名一致。

第三步:全局搜索残留的 www 链接

数据库里、模板文件里、插件目录里,都可能藏着写死的 www.yangchao.net:

 
grep -r "www.yangchao.net" /path/to/content/templates/
grep -r "www.yangchao.net" /path/to/content/plugins/
 

数据库里也要查:

 
SELECT * FROM emlog_blog WHERE content LIKE '%www.yangchao.net%';
SELECT * FROM emlog_options WHERE option_value LIKE '%www.yangchao.net%';
SELECT * FROM emlog_navi WHERE url LIKE '%www.yangchao.net%';
 

第四步:清缓存

EMLOG 后台 → 缓存管理 → 清除缓存;浏览器 Ctrl + F5 强刷。


六、最终解决方案

方案一:服务器层做 301 跳转(最推荐)

在 Nginx 里给 www.yangchao.net 单独建一个 server 块,永久跳转到不带 www 的地址:

 
server {
    listen 443 ssl;
    server_name www.yangchao.net;

    ssl_certificate     /path/to/your.crt;
    ssl_certificate_key /path/to/your.key;

    return 301 https://yangchao.net$request_uri;
}
 

注意​:不要在 rewrite 里写 ^https://www.yangchao.net,因为 rewrite 只匹配 URI 部分,不匹配协议和域名,那条规则永远不会生效。

方案二:数据库批量替换

 
UPDATE emlog_blog
SET content = REPLACE(content, 'www.yangchao.net', 'yangchao.net')
WHERE content LIKE '%www.yangchao.net%';
 

其他表类似,注意先 SELECT 确认,再 UPDATE 替换。

方案三:模板/插件文件里写死的链接

全局搜索 www.yangchao.net,改成 <?= BLOG_URL ?> 或直接改成不带 www 的地址。


七、经验总结

这次排查踩了四个坑,按顺序是:

坑 表现 真正原因
1 以为更新 jQuery 能解决 问题不在文件,在服务器响应头
2 不知道 ORB 是什么 浏览器安全机制拦截了 MIME 不对的资源
3 没注意域名不一致 yangchao.net 和 www.yangchao.net 是不同源
4 只在页面层面找问题 数据库、模板、插件里都可能有残留链接

核心教训​:

  1. 看报错要看完整链条​。$ is not defined 只是表象,真正的错误在上面几行。
  2. 跨域问题优先查域名一致性​。带 www 和不带 www,在浏览器眼里是两个世界。
  3. ORB 拦截的本质是 MIME 类型不匹配​。服务器返回 JS 文件时,Content-Type 必须是 application/javascript。
  4. 服务器层 301 跳转是一劳永逸的方案​。即使数据库有残留,用户点击也会自动跳回,不会触发跨域。

八、给遇到同类问题的朋友

如果你也遇到:

  • A resource is blocked by OpaqueResponseBlocking
  • $ is not defined / jQuery is not defined
  • 页面功能突然大面积失效

可以按这个顺序排查:

  1. F12 → Network,看失败请求的 Content-Type 和请求域名
  2. 确认页面地址和资源地址是否同源(协议、域名、端口都要一致)
  3. 检查 CMS 后台的站点地址设置
  4. 全局搜索数据库和文件里是否有旧域名残留
  5. 服务器层加 301 跳转统一域名
  6. 清缓存,强刷验证

整个过程不复杂,但坑比较隐蔽。希望这篇记录能帮你少走弯路。


本文记录于 2026 年 9 月,问题环境:EMLOG 博客系统 + Nginx + 自定义模板。

评论
更换验证码
友情链接