Spring Boot中S3预签名URL下载PDF显示损坏问题求助
使用S3预签名URL下载PDF时文件损坏问题
我在使用S3预签名URL时遇到问题:通过该URL下载PDF时,浏览器提示文件已损坏,但直接通过字节流下载却能正常获取文件。
我的代码:
public URL getSignedURL(FileS3 filesS3) { if (!clienteS3.doesBucketExistV2(bucketName)) { System.out.println("指定的存储桶不存在 [" + bucketName + "]。"); throw new NullPointerException("指定的存储桶不存在 [" + bucketName + "]。"); } java.util.Date expiration = new java.util.Date(); long expTimeMillis = Instant.now().toEpochMilli(); expTimeMillis += MySettings.AWS_S3_EXPIRATION_TIME; expiration.setTime(expTimeMillis); // // 生成预签名URL。 System.out.println("正在生成预签名URL。"); GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, filesS3.getUrl()) .withMethod(HttpMethod.GET) .withExpiration(expiration); URL url = clienteS3.generatePresignedUrl(generatePresignedUrlRequest); // filesS3.setPreSignedUrl(url); // return url; }
已尝试的解决方案:
- 指定Content Type,但出现S3错误提示:“请求签名与提供的签名不匹配,请检查密钥和签名方法”
解决思路
对齐Content-Type配置
之前指定Content-Type触发签名不匹配,是因为生成预签名URL时设置的Content-Type,和浏览器实际请求时发送的头信息不一致。生成URL时用withContentType("application/pdf")明确指定类型,同时确保请求时浏览器携带相同的Content-Type头,签名验证就能通过。检查S3对象元数据
确认S3上的PDF文件元数据中,Content-Type是否已设为application/pdf。如果元数据错误,浏览器会以错误的方式解析文件,导致损坏提示。可以通过S3控制台查看或在上传文件时直接指定正确的元数据。校验对象键编码
检查filesS3.getUrl()返回的对象键是否包含特殊字符(空格、中文、特殊符号),这类字符需要正确URL编码后再用于生成预签名URL,否则会指向错误的对象,下载到损坏内容。用curl验证URL有效性
用curl工具测试预签名URL,对比直接字节流下载的内容:curl -o test.pdf "你的预签名URL"若curl下载的文件正常,说明问题出在浏览器端(比如缓存、自动解析逻辑),可以尝试清除浏览器缓存或用隐私模式测试。
升级AWS SDK版本
旧版本SDK可能存在预签名URL生成的bug,升级到最新版SDK后再测试问题是否消失。
内容的提问来源于stack exchange,提问作者KenobiBastila
相关产品推荐
相关产品推荐

