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

无法控制跨域头时,JS跨域获取第三方托管文件大小的方案

解决跨域获取文件大小并提供下载的方案

针对你遇到的跨域无法通过HEAD请求获取Content-Length的问题,以下是几种可行的解决思路:

  • 使用范围请求获取文件大小
    发起仅请求文件前1字节的范围请求,通过响应头中的Content-Range字段提取总文件大小。示例代码如下:

    async function getFileSize(url) {
      try {
        const response = await fetch(url, {
          headers: {
            'Range': 'bytes=0-0'
          }
        });
        if (!response.ok) throw new Error('请求失败');
        const contentRange = response.headers.get('Content-Range');
        if (!contentRange) return null;
        // 从Content-Range解析总大小,格式为"bytes 0-0/12345"
        const totalSize = parseInt(contentRange.split('/')[1], 10);
        return totalSize;
      } catch (err) {
        console.error('获取文件大小失败:', err);
        return null;
      }
    }
    
    // 调用示例
    const pdfUrl = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
    getFileSize(pdfUrl).then(size => {
      const a = document.createElement('a');
      a.href = pdfUrl;
      a.download = 'dummy.pdf';
      if (size !== null) {
        const displaySize = (size / 1024 / 1024).toFixed(2) + ' MB';
        a.textContent = `Download PDF (${displaySize})`;
      } else {
        a.textContent = 'Download PDF';
      }
      document.body.appendChild(a);
    });
    

    注意:该方法依赖服务器支持范围请求(返回Accept-Ranges: bytes头),且允许前端读取Content-Range头(即服务器返回Access-Control-Expose-Headers: Content-Range),不满足则无法生效。

  • 下载文件到内存后获取大小
    如果范围请求不可行,可先完整下载文件为Blob对象,通过Blob的size属性获取大小后再创建下载链接。示例代码:

    async function downloadAndShowSize(url) {
      try {
        const response = await fetch(url);
        if (!response.ok) throw new Error('下载失败');
        const blob = await response.blob();
        const totalSize = blob.size;
        const displaySize = (totalSize / 1024 / 1024).toFixed(2) + ' MB';
        
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = 'dummy.pdf';
        a.textContent = `Download PDF (${displaySize})`;
        document.body.appendChild(a);
        
        // 点击后释放Blob URL避免内存泄漏
        a.addEventListener('click', () => {
          setTimeout(() => URL.revokeObjectURL(a.href), 100);
        });
      } catch (err) {
        console.error('处理失败:', err);
        // 降级展示原下载链接
        const a = document.createElement('a');
        a.href = url;
        a.download = 'dummy.pdf';
        a.textContent = 'Download PDF';
        document.body.appendChild(a);
      }
    }
    
    // 调用示例
    downloadAndShowSize('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf');
    

    缺点:需等待文件下载完成才能展示大小,大文件会增加等待时间和浏览器内存占用。

  • 硬编码固定文件大小(仅适用于文件不更新的场景)
    如果目标文件长期不变,可手动通过浏览器开发者工具或curl命令获取文件大小(比如执行curl -I https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf查看Content-Length值),直接将数值写死在页面代码中,创建带大小标注的下载链接。

内容的提问来源于stack exchange,提问作者Aelita

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:28:35