无法控制跨域头时,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
相关产品推荐
相关产品推荐

