微信短链无法用PHP直接还原,因其采用服务端302跳转+前端JS混淆双重保护,cURL不执行JS且受UA、Cookie限制,仅能处理

微信短链接无法直接用 PHP 解析还原,因为 weixin.qq.com 类短链(如 https://w.url.cn/s/AbCdEfG)是服务端 302 跳转 + 前端 JS 混淆双重保护,PHP 的 get_headers() 或 cURL 默认拿不到最终 URL —— 它们会被重定向拦截,且部分跳转还依赖微信客户端 UA 和 Cookie。
为什么 curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) 失败
微信短链的跳转链路通常是:短链 → 中间页(含 JS 跳转)→ 目标页。cURL 默认不执行 JS,所以即使开启 CURLOPT_FOLLOWLOCATION,也只走到中间 HTML 页面,CURLINFO_EFFECTIVE_URL 返回的是中间页地址(如 https://mp.weixin.qq.com/s?__biz=xxx 的壳页面),不是真实目标 URL。
- 中间页响应头通常不含
Location,而是返回一段含window.location.href = "..."或 Base64 混淆字符串的 HTML - 微信会校验
User-Agent,非微信 UA(如 cURL 默认值)可能被返回 403 或降级为二维码页 - 部分短链还依赖
cookie(如pgv_pvi、mm_lang),空 cookie 会导致跳转中断
用浏览器开发者工具抓包的真实流程
这不是“打开 F12 看一眼就完事”,关键在于捕获**首次跳转后的那个带 Location 响应头的请求**,它往往藏在 XHR 或 Fetch 请求里,或由前端 JS 触发的隐藏 iframe 加载中。
- 在 Chrome 打开微信短链(需用微信内置浏览器或通过「微信开发者工具」模拟,普通 Chrome 会跳转失败)
- F12 → Network → 勾选「Preserve log」→ 刷新页面
- 过滤
XHR和Doc,找到第一个返回 302 的请求(响应头含Location: https://mp.weixin.qq.com/...) - 右键该请求 → 「Copy」→ 「Copy as cURL (bash)」,粘贴到终端可验证是否能复现跳转
- 若没看到 302,点开任意一个 HTML 响应 → 查看 Response → 搜索
location.href或base64字符串,手动解码
PHP 中模拟可行但有限的还原方式
只能处理「纯服务端 302 跳转」的极少数微信短链(实际占比<5%),对主流 w.url.cn 无效。必须严格设置请求头和 Cookie,并禁用自动跳转以便逐层检查。
立即学习“PHP免费学习笔记(深入)”;
function resolveWechatShortUrl($shortUrl) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $shortUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // 关键:不能自动跳
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.49(0x18003133) NetType/WIFI Language/zh_CN');
curl_setopt($ch, CURLOPT_COOKIE, 'mm_lang=zh_CN; pgv_pvi=1234567890;');
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
if (preg_match('/Location:\s*(.+)/i', $headers, $matches)) {
return trim($matches[1]);
}
// 若无 Location,尝试从 body 提取 JS 跳转(简单匹配,不保证 100%)
if (preg_match('/window\.location\.href\s*=\s*[\'"]([^\'"]+)[\'"]/i', $body, $matches)) {
return $matches[1];
}
curl_close($ch);
return null;
}
这个函数对大部分 w.url.cn 返回 null,因为它的 body 是加密 script 标签或 canvas 渲染页 —— 这正是为什么必须依赖浏览器抓包,而不是幻想 PHP 单独搞定。
真正稳定还原微信短链,唯一可靠路径是:用 Puppeteer 或 Playwright 启动真实 Chromium,注入微信 UA,等 JS 执行完再读 window.location.href;或者,直接信任抓包拿到的那条 302 响应头 —— 其他所有“PHP 解密算法”“Base64 反混淆”都是针对过期样本的无效尝试。











