上传PDF到S3需设置哪些头实现浏览器预览而非下载?首次加载报错如何解决
问题说明
在多数同类问题中,添加ContentDisposition = 'inline'即可解决PDF默认被下载的问题,以下是上传PDF时传递的参考参数:
Bucket: `${cookieJS.Bucket}${item.url !== '' ? `/${item.url}` : ''}`, Key: decodeURIComponent(`${this.kebabCaseName(item.name)}`), Body: item.entry, ACL: cookieJS.ACL, ContentType: item.entry.type, // application/pdf ContentDisposition: 'inline',
完成上述修改后PDF已不会默认下载,但访问PDF链接时,Chrome首次打开会提示“加载文档失败”,刷新后才能正常加载,需要明确首次加载报错的原因,以及在不支持刷新的应用中正常访问PDF的方案。
首次加载报错的核心原因
- Chrome内置PDF查看器会在资源尚未完全加载完成时就提前解析文档头,如果存储服务返回的响应头缺少
Content-Length字段,或是开启了分片传输(Transfer-Encoding: chunked)但未正确支持范围请求(Accept-Ranges: bytes),就会导致首次解析失败,第二次加载时浏览器已有部分缓存,即可正常解析 - 若存储服务的跨域规则未放行
Range请求头,也会触发该错误 - 部分场景下Chrome会自动嗅探资源类型,缺少
X-Content-Type-Options: nosniff响应头时可能出现类型识别偏差,导致加载失败
修复方案
- 补充上传参数
上传PDF时额外添加两个配置项:
// 新增参数 ContentLength: item.entry.size, ContentEncoding: 'identity', // 原有参数保留 Bucket: `${cookieJS.Bucket}${item.url !== '' ? `/${item.url}` : ''}`, Key: decodeURIComponent(`${this.kebabCaseName(item.name)}`), Body: item.entry, ACL: cookieJS.ACL, ContentType: item.entry.type, // application/pdf ContentDisposition: 'inline',
- 调整存储桶跨域配置
在对应存储服务的跨域CORS规则中,允许Range请求头,同时放行Content-Range响应头 - 应用侧兼容(适用于无法修改存储配置的场景)
在不支持刷新的应用内,使用PDF.js替代Chrome内置PDF查看器渲染文件,加载时先完整拉取PDF的Blob对象再传入渲染,即可规避首次加载失败的问题
内容的提问来源于stack exchange,提问作者imavinash
相关产品推荐
相关产品推荐

