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

PHP获取网站JS文件大小失败:无法读取含../路径及文件不存在错误

解决PHP统计网站JS文件大小无法处理相对路径的问题

嘿,我完全懂你遇到的坑——直接把../test.js这类相对路径丢给file_get_contents时,PHP会把它当成你本地服务器的文件路径去查找,而不是相对于目标网站页面的URL,自然就会报找不到文件的错误。下面是具体的解决方案,一步步来帮你搞定:

核心思路

相对路径是基于当前页面的URL来解析的,不是本地路径。所以我们需要:

  1. 把页面中的相对JS路径转换成完整的绝对URL
  2. 通过绝对URL请求远程JS文件,再统计其实际大小

具体实现代码

第一步:编写相对路径转绝对URL的工具函数

这个函数能处理各种类型的相对路径(../test.js、./script.js、/assets/main.js),把它们转换成可直接请求的绝对URL:

function resolve_absolute_url($relative, $base) {
    $base_parsed = parse_url($base);
    $relative_parsed = parse_url($relative);

    // 如果已经是绝对URL,直接返回
    if (isset($relative_parsed['scheme'])) {
        return $relative;
    }

    // 处理基础URL的路径:如果是文件路径,取它的目录部分
    $base_path = isset($base_parsed['path']) ? $base_parsed['path'] : '/';
    if (strpos($base_path, '.') !== false) {
        $base_path = dirname($base_path);
    }

    // 拼接相对路径并解析../和./
    $relative_path = isset($relative_parsed['path']) ? $relative_parsed['path'] : '';
    $combined_path = rtrim($base_path, '/') . '/' . ltrim($relative_path, '/');
    $parts = explode('/', $combined_path);
    $new_parts = [];
    foreach ($parts as $part) {
        if ($part === '..') {
            array_pop($new_parts);
        } elseif ($part !== '.') {
            $new_parts[] = $part;
        }
    }
    $absolute_path = implode('/', $new_parts);

    // 拼接完整URL,包含协议、主机、端口和查询参数
    $absolute_url = "{$base_parsed['scheme']}://{$base_parsed['host']}";
    if (isset($base_parsed['port'])) {
        $absolute_url .= ":{$base_parsed['port']}";
    }
    $absolute_url .= "/".ltrim($absolute_path, '/');

    // 保留查询参数(比如?v=1这类缓存标识)
    if (isset($relative_parsed['query'])) {
        $absolute_url .= "?{$relative_parsed['query']}";
    }

    return $absolute_url;
}

第二步:主流程——解析页面、获取JS并统计大小

这里我们用DOMDocument解析页面中的<script>标签,转换路径后请求文件并计算大小:

// 用户传入的目标网站URL
$target_url = 'https://example.com/path/page.html';

// 获取目标页面内容(如果allow_url_fopen关闭,建议用下面的cURL替代)
$page_content = file_get_contents($target_url);
if (!$page_content) {
    die('无法加载目标页面,请检查URL是否正确或网络连接');
}

// 解析HTML中的script标签(用@忽略不规范HTML的解析警告)
$dom = new DOMDocument();
@$dom->loadHTML($page_content);
$scripts = $dom->getElementsByTagName('script');

$js_size_stats = [];

foreach ($scripts as $script) {
    $src = $script->getAttribute('src');
    if (empty($src)) continue; // 跳过内联脚本

    // 转换相对路径为绝对URL
    $absolute_js_url = resolve_absolute_url($src, $target_url);

    // 获取JS文件内容(推荐用cURL替代file_get_contents,更稳定)
    $js_content = @file_get_contents($absolute_js_url);
    if ($js_content === false) {
        $js_size_stats[$absolute_js_url] = '请求失败:无法获取该JS文件';
        continue;
    }

    // 计算大小(字节转KB保留两位小数)
    $size_bytes = strlen($js_content);
    $size_kb = round($size_bytes / 1024, 2);
    $js_size_stats[$absolute_js_url] = "{$size_bytes} 字节 ({$size_kb} KB)";
}

// 输出统计结果
echo "<h2>网站JS文件大小统计</h2>";
foreach ($js_size_stats as $url => $info) {
    echo "<p><strong>{$url}</strong>: {$info}</p>";
}

备选:用cURL替代file_get_contents(更稳定)

如果你的PHP环境关闭了allow_url_fopen,可以用这个函数代替file_get_contents:

function get_remote_content($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自动处理重定向
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 根据需求开启/关闭SSL验证
    $content = curl_exec($ch);
    curl_close($ch);
    return $content;
}

然后把主流程里的file_get_contents替换成get_remote_content即可。

注意事项

  • 确保PHP的allow_url_fopen配置开启(如果用file_get_contents的话),或者启用cURL扩展
  • 有些网站可能有防盗链机制,直接请求JS文件会失败,这种情况可以在cURL里设置CURLOPT_HTTPHEADER模拟浏览器请求头
  • 解析HTML时用@忽略警告是因为很多网站的HTML不规范,DOMDocument会抛出大量不影响功能的警告

内容的提问来源于stack exchange,提问作者Noor B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:28:33