diegomura / react-pdf

📄 Create PDF files using React
https://react-pdf.org
MIT License
14.97k stars 1.19k forks source link

No 'Access-Control-Allow-Origin' header is present on the requested resource. #766

Closed rakeshbijoriyagate6 closed 3 years ago

rakeshbijoriyagate6 commented 5 years ago

Describe the bug Using this component to generate pdfs in the react Project. But having an issue with Image when I am using images from cloudfront.net images are not showing in generated pdfs. when I console it is showing "Access to XMLHttpRequest at 'http://dgzr31xopt5l5.cloudfront.net/profile_pics/FnB7YJOtWsVyvHN8dKEyvbNmV9V21570438881789.png' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource." this error.

To Reproduce To generate same issue use below code in MyDocument.js component. " <Image style={{ width: 100, height: 100, borderRadius: 50 }} src='https://dgzr31xopt5l5.cloudfront.net/profile_pics/FnB7YJOtWsVyvHN8dKEyvbNmV9V21570438881789.png' cache="false" crossOrigin="anonymous" allowDangerousPaths="true" />"

Please provide some solution to this issue as soon as possible.

cworf commented 4 years ago

Im curious about this issue as well. having the same problem.

chadwilken commented 4 years ago

It looks like you need to change how the internal fetch execution is performed. If we can pass along options to fetch, I could get it to work using fetch(url, { cache: 'reload' }). An alternative method (depending on your CloudFront config) is to append some random value to the URL as a query string and it will break the cache.

chadwilken commented 4 years ago

Found an even better way:

<Image
  source={{
    uri: imageUrl,
    headers: { Pragma: 'no-cache', 'Cache-Control': 'no-cache' },
  }}
/>

Those headers will force the browser to check the server to see if the content has changed and then skips the cache.

hyun-park commented 4 years ago

I'm getting images from AWS S3.

<Image
  src={ imageUrl + `?noCache=` + randomString }
  source={{
    header: {
       'Access-Control-Allow-Origin': '*'
    }
  }}
/>

This works for me. ?noCache query string and randomString can be whatever you want.

primordius commented 4 years ago

If you are using AWS S3, make sure your bucket has a proper Cross-origin resource sharing and you are setting the random query string mentioned above https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors Example CORS policy:

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

Document:

<Image
  src={imageSource + '?noCache=' + Math.random().toString()}
/>
danielbyun commented 4 years ago

@primordius @hyun-park

Are your S3 buckets public? My S3 buckets that contain the images are private, so when I follow you guys' instructions I get the 403 (Forbidden) error with Not valid image extension error.

chadwilken commented 4 years ago

@danielbyun unless you’re using a pre-signed URL you will more than likely have to handle requesting the image manually and then passing the data. If you are using a pre-signed URL then I imagine it should just work as long as all of the params and headers match what youUsed when you generated the URL.

danielbyun commented 4 years ago

Hi @chadwilken,

Thank you for your response. The images are being fetched and processed with the pre-signed URLs on the backend and the frontend is just receiving the URL.

When I console.log() and click the S3 image link URL, it automatically downloads, which I think means the images are accessible and viewable.

Are there any other necessary steps I need to take in order to render the images? In any other component in this project, I have no problem rendering the images except in this package.

I've tried doing this to no avail. <Image source={{ uri: {imageURL}, method: "get", headers:{ "Access-Control-Allow-Origin": "*", crossOrigin: "anonymous" } }} cache={false} allowDangerousPaths={true}></Image>

Thanks for your help.

chadwilken commented 4 years ago

@danielbyun to the best of my knowledge the request has to match exactly what you use when you generate the presigned URL. I would open up the network inspector and see what headers are being sent when the image is requested by React PDF and then try adding that to your presigned URL. If you want to debug it without going through React PDF you can use the console and execute the same code that React PDF does by initing an image, setting the src, etc. You can use this file for reference on what it is doing (just select whatever version you're using obviously).

danielbyun commented 4 years ago

@chadwilken

Upon carefully inspecting the network tab, the S3 pre-signed URL is returning a Content-Type of application/octet-stream inside Response Headers.

Can I convert this into an image file with an extension of .jpg or .png or do I need to change the Content-Type inside the pre-signed URL to be an image file before sending it to the client?

chadwilken commented 4 years ago

You probably need to change the content type header.

iamAbdulAhad3481 commented 4 years ago

@chadwilken i am facing same error i tried all the above things you or other mention nothing works but when i added <Image style={styles.image} source={{ uri: https://cors-anywhere.herokuapp.com/${companyLogo}}} /> . It works Can you please help me in acheiveing a more clear way. Screenshot 2020-07-27 at 14 29 06

chadwilken commented 4 years ago

@AbdulAhad125 I don't really have enough info here to debug anything. I suggest looking at the source code to see how it works internally.

diegomura commented 3 years ago

@AbdulAhad125 you are missing the headers (please read comments above). If this still fails it's probably the image path that does accepts the correct CORS headers

akshat-rastogi commented 3 years ago

Found an even better way:

<Image
  source={{
    uri: imageUrl,
    headers: { Pragma: 'no-cache', 'Cache-Control': 'no-cache' },
  }}
/>

Those headers will force the browser to check the server to see if the content has changed and then skips the cache.

This worked for me. Thank you.

ryancarville commented 3 years ago

I am facing the same issues. Tried all the above and no luck.

First, I get a clean response form Dynamo that holds the image url to a public S3 Bucket. Then when that image url value is applied to
<Image src={imagePathHere}/> it CORS errors out and it not applied to the final PDF. (All text renders out fine)

Odd thing is that the network tab shows the correct path being used with a 200OK status and the image preview. When this path is used in the browser is loads and downloads fine.

Super frustration and any help is appreciated

LuizLeite commented 2 years ago

Same issue here. By IMG error not occurs, only in IMAGE occurs.

Nutriadmin commented 1 year ago

Please check #2340 for how I've solved this issue by making my server convert images to base64. This will work even when loading images from an external website that has a CORS policy you cannot control.