0

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

Loudrous
  • 1,039
  • 10
  • 29
  • 1
    You seem to be asking the same question repeatedly, after deleting the prior variant of the question. This is the 4th version of the same, or very similar, question afaik. That's not how Stack Overflow works. Correct the issues in the original question rather than keep asking the same question until you find an answer that you like. – jarmod Jun 29 '22 at 17:54
  • At least [one](https://stackoverflow.com/questions/72764740/how-to-fix-aws-s3-corb-error-with-pdf-files) of your prior duplicates of this question was not downvoted. Please don't keep opening the same question. Some ideas: 1) Make sure that the content you are serving includes the correct Content-Type response header of application/pdf. 2) Try your React component pointing to a publicly-accessible PDF instead of the response from your app server. 3) Try using a different PDF viewer component (not the one you're using now). – jarmod Jun 29 '22 at 20:35

0 Answers0