AWS存储桶可以在特定路由上显示PDF文件
我的NextJS应用程序( v12.1.3 )允许用户上传文件。服务器将它们存储在AWS S3存储桶中。
我以这种方式存储它们:
import _ from 'lodash';
import AWS from 'aws-sdk';
import { v4 as uuidv4 } from 'uuid';
import { config } from '../config';
// file is in base64 format
const uploadFileToS3 = async (file: string) => {
const s3 = new AWS.S3({
accessKeyId: config.AWS_ACCESS_KEY_ID,
secretAccessKey: config.AWS_SECRET_ACCESS_KEY,
signatureVersion: 'v4',
region: 'eu-south-1',
});
const contentType = file.split(':')[1].split(';')[0];
const params = {
Key: uuidv4(),
Body: Buffer.from(file.replace(/^data:.+;base64,/, ''), 'base64'),
Bucket: config.AWS_S3_BUCKET_NAME,
ContentType: contentType,
};
return await s3.upload(params).promise();
};
export default uploadFileToS3;
我的存储桶设置:
阻止公共访问(存储桶设置) - > OFF
存储策略
{ “版本”:“ 2012-10-17”, “陈述”: [ { “ sid”:“ publicReadgetObject”, “效果”:“允许”, “主要的”: ”*”, “动作”:“ s3:getObject”, “资源”:“ Arn:AWS:S3 ::: My-Test-Bucket/*” } 这是给出的 }
交叉原始资源共享(CORS)
[ { “允许的人”:[], “允许的方法”:[ “得到” ],, “允许的人”:[ “*” ],, “ ExposeHeaders”:[] } 这是给出的
从uploadfiletos3
方法返回的URL。
客户端相反,我使用此URL查看图像和PDF文件。 问题 是在某个路由上/generic-entity/{id}
我无法预览.pdf文件(没有问题.jpeg或.png文件)。
我遇到了这个错误(甚至是警告):
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://xxxxxx.execute-api.us-east-2.amazonaws.com/default/xxxxxx with MIME type application/pdf. See https://www.chromestatus.com/feature/5629709824032768 for more details.
我环顾四周,发现这是一个新的Web平台安全功能,可帮助减轻侧通道攻击的威胁
在路由上/generic-entity
我可以预览PDF文件。不同之处在于,在最后一个上,有一个自动进入AWS:
curl 'https://my-test-bucket.s3.eu-south-1.amazonaws.com/e751b456-c996-4747-bcef-03021cd80357__foo__Doc%2520base.pdf' \
-H 'Accept: */*' \
-H 'Accept-Language: en,en-US;q=0.9,it-IT;q=0.8,it;q=0.7' \
-H 'Connection: keep-alive' \
-H 'If-Modified-Since: Sun, 26 Jun 2022 19:21:16 GMT' \
-H 'If-None-Match: "9b1027ca72e993b2607ba5b54e735c64"' \
-H 'Origin: http://localhost:3000' \
-H 'Referer: http://localhost:3000/' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: cross-site' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "macOS"' \
--compressed
另一个是没有一个。我试图手动做,但没有解决问题。
有关主要详细信息,这是我用来预览PDF文件的React组件:
// import default react-pdf entry
import { Document, Page, pdfjs } from 'react-pdf';
// import pdf worker as a url, see `next.config.js` and `pdf-worker.js`
import workerSrc from '../../pdf-worker';
pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;
interface Props {
file: any;
className?: string;
}
//in this case file is a url.
const PDFPreview: React.FC<Props> = ({ file, className }) => {
function onDocumentLoadSuccess() {
document
.getElementById('react-pdf__Page__canvas')
?.style.setProperty('display', 'flex', 'important');
}
return (
<div
className={`flex overflow-y-hidden rounded-lg cursor-pointer ${className}`}
>
<Document file={file} onLoadSuccess={onDocumentLoadSuccess}>
<Page
key={`page_${1}`}
pageNumber={1}
renderAnnotationLayer={false}
renderTextLayer={false}
className="flex w-full"
style={{ display: 'flex' }}
/>
</Document>
</div>
);
};
export default PDFPreview;
您对如何解决此问题有任何建议吗?
ps i也在 vercel 。您可以在路由/my-entity
上看到它有效,而在路由/my-entity/1
不使用相同的URL和相同的React组件
My nextjs app (v12.1.3) allows users to upload files. The server stores them in an AWS s3 bucket.
I store them in this way:
import _ from 'lodash';
import AWS from 'aws-sdk';
import { v4 as uuidv4 } from 'uuid';
import { config } from '../config';
// file is in base64 format
const uploadFileToS3 = async (file: string) => {
const s3 = new AWS.S3({
accessKeyId: config.AWS_ACCESS_KEY_ID,
secretAccessKey: config.AWS_SECRET_ACCESS_KEY,
signatureVersion: 'v4',
region: 'eu-south-1',
});
const contentType = file.split(':')[1].split(';')[0];
const params = {
Key: uuidv4(),
Body: Buffer.from(file.replace(/^data:.+;base64,/, ''), 'base64'),
Bucket: config.AWS_S3_BUCKET_NAME,
ContentType: contentType,
};
return await s3.upload(params).promise();
};
export default uploadFileToS3;
My bucket settings:
Block public access (bucket settings) -> OFF
Bucket policy
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-test-bucket/*" } ] }
Cross-origin resource sharing (CORS)
[ { "AllowedHeaders": [], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ]
I store in my mongo DB the url returned from uploadFileToS3
method.
Client side, instead, I use this url to view images and pdf files. The problem is that on a certain route /generic-entity/{id}
I cannot preview the .pdf files (there is no problems with .jpeg or .png files).
I get this error (even it is a warning):
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://xxxxxx.execute-api.us-east-2.amazonaws.com/default/xxxxxx with MIME type application/pdf. See https://www.chromestatus.com/feature/5629709824032768 for more details.
and I looked around and found out it is a new web platform security feature that helps mitigate the threat of side-channel attacks
Instead on the route /generic-entity
I can preview the pdf files. The difference is that on this last one there is a automatic GET to the aws like this one:
curl 'https://my-test-bucket.s3.eu-south-1.amazonaws.com/e751b456-c996-4747-bcef-03021cd80357__foo__Doc%2520base.pdf' \
-H 'Accept: */*' \
-H 'Accept-Language: en,en-US;q=0.9,it-IT;q=0.8,it;q=0.7' \
-H 'Connection: keep-alive' \
-H 'If-Modified-Since: Sun, 26 Jun 2022 19:21:16 GMT' \
-H 'If-None-Match: "9b1027ca72e993b2607ba5b54e735c64"' \
-H 'Origin: http://localhost:3000' \
-H 'Referer: http://localhost:3000/' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: cross-site' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "macOS"' \
--compressed
on the other one instead there's is none. I tried to do it manually but it didn't solve the problem.
For major details here's the react component I use to preview the pdf file:
// import default react-pdf entry
import { Document, Page, pdfjs } from 'react-pdf';
// import pdf worker as a url, see `next.config.js` and `pdf-worker.js`
import workerSrc from '../../pdf-worker';
pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;
interface Props {
file: any;
className?: string;
}
//in this case file is a url.
const PDFPreview: React.FC<Props> = ({ file, className }) => {
function onDocumentLoadSuccess() {
document
.getElementById('react-pdf__Page__canvas')
?.style.setProperty('display', 'flex', 'important');
}
return (
<div
className={`flex overflow-y-hidden rounded-lg cursor-pointer ${className}`}
>
<Document file={file} onLoadSuccess={onDocumentLoadSuccess}>
<Page
key={`page_${1}`}
pageNumber={1}
renderAnnotationLayer={false}
renderTextLayer={false}
className="flex w-full"
style={{ display: 'flex' }}
/>
</Document>
</div>
);
};
export default PDFPreview;
Do you have any suggestion on how to fix this?
P.S. I also replicated this error in this github repo and I deployed it on vercel. You can see that on the route /my-entity
it works, while on the route /my-entity/1
doesn't using the same url and the same react component
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论