Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't consistently see images loaded via loadImageFromURL #68

Open
humblecoder opened this issue Oct 5, 2018 · 46 comments
Open

Can't consistently see images loaded via loadImageFromURL #68

humblecoder opened this issue Oct 5, 2018 · 46 comments
Labels

Comments

@humblecoder
Copy link

humblecoder commented Oct 5, 2018

Version

3.2.0

Development Environment

MacOS 10.12.6
Chrome Version 69.0.3497.100 (Official Build) (64-bit)

Current Behavior
Using loadImageFromURL doesn't consistently display image. Occasionally there is a CORS error, despite the resource being fully configured for CORS. And sometimes it will load fine. It's fairly random. I am using the same test images for all tests. I can, with 100% certainty load the same images to <img> tags as well as to a raw fabric.js instance.

Are there any updated (perhaps undocumented) steps to take after loading an image via loadImageFromURL? Is a canvas refresh/resize required? Must I perform some step in the Promise after the fact? I'm hoping I'm simply missing something, but this is a fairly frustrating occurrence.

UPDATE:
So, apparently, (in Chrome) when the dev tools are open it works. When the dev tools are closed, it fails. Video of issue in action.

When the tools are closed I receive Access-Control-Allow-Origin error. This, despite the fact that the resources are publicly accessible and currently configured to allow all '*'. You can see in the video the same resources being "previewed" in the grid via <img> tags. However, when attempting to open a modal and simply call loadImageFromURL it fails. I've tried nextTick and a host of other "hacks", but nothing seems to matter other than dev tools being opened or closed.

FYI, I'm console.loging nearly everything. Occasionally I receive an executing command state is locked error from the editor instance as well. No idea what that means.

@emyl3
Copy link

emyl3 commented Oct 18, 2018

I am also having this issue as well! Particularly when loading the image editor from a browser on iPad.

@VitaliyOnRule
Copy link

Version

3.2.0

Development Environment

MacOS 10.12.6
Chrome Version 69.0.3497.100 (Official Build) (64-bit)

Current Behavior
Using loadImageFromURL doesn't consistently display image. Occasionally there is a CORS error, despite the resource being fully configured for CORS. And sometimes it will load fine. It's fairly random. I am using the same test images for all tests. I can, with 100% certainty load the same images to <img> tags as well as to a raw fabric.js instance.

Are there any updated (perhaps undocumented) steps to take after loading an image via loadImageFromURL? Is a canvas refresh/resize required? Must I perform some step in the Promise after the fact? I'm hoping I'm simply missing something, but this is a fairly frustrating occurrence.

UPDATE:
So, apparently, (in Chrome) when the dev tools are open it works. When the dev tools are closed, it fails. Video of issue in action.

When the tools are closed I receive Access-Control-Allow-Origin error. This, despite the fact that the resources are publicly accessible and currently configured to allow all '*'. You can see in the video the same resources being "previewed" in the grid via <img> tags. However, when attempting to open a modal and simply call loadImageFromURL it fails. I've tried nextTick and a host of other "hacks", but nothing seems to matter other than dev tools being opened or closed.

FYI, I'm console.loging nearly everything. Occasionally I receive an executing command state is locked error from the editor instance as well. No idea what that means.

Have You already solved that problem? If yes - how?

@humblecoder
Copy link
Author

humblecoder commented Nov 16, 2018

@VitaliyOnRule I have not solved the problem. Although it does for some random reason seem to occur far less often.

@emyl3
Copy link

emyl3 commented Dec 5, 2018

@humblecoder and @VitaliyOnRule I had the same issue of the images not loading consistently. I think it may have been some caching issue for me. It was an amazon s3 url.

When I loaded the image I added the following cache busting query param to the image url string + '?t=' + new Date().getTime().

This answer was from here:
https://stackoverflow.com/questions/1077041/refresh-image-with-a-new-one-at-the-same-url/22429796#22429796

@humblecoder
Copy link
Author

@emyl3 and @VitaliyOnRule I actually ended up using my server as a "proxy" and loading the image from base64 😞. Appreciate the input though.

@VitaliyOnRule
Copy link

@humblecoder and @VitaliyOnRule I had the same issue of the images not loading consistently. I think it may have been some caching issue for me. It was an amazon s3 url.

When I loaded the image I added the following cache busting query param to the image url string + '?t=' + new Date().getTime().

This answer was from here:
https://stackoverflow.com/questions/1077041/refresh-image-with-a-new-one-at-the-same-url/22429796#22429796

It is not a simple issue. But the only one way to solve it for 100% -is to write a proxy server or throw image via route of your server. Because some of remote s3 buckets and cloudflare/cloudfront mediators have origin white lists on their configurations and it is blocking access to the image from the javascript anyway. So to make it working for 100% - just get images via your backend

@bpautsch
Copy link

bpautsch commented Oct 1, 2019

Using v3.2.2, the editor never loads images located in Amazon S3.
I have the CORS Configuration setup with:
Access-Control-Allow-Origin

I always receive error:
Access to image at 'https://xxx.s3.amazonaws.com/assets/custom/000364/images/web/flowers-2.jpg' from origin 'https://www.yyy.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here's an interesting thread I found about it:
https://stackoverflow.com/questions/54155431/toastui-image-editor-loadimagefromurl-doesnt-work

@Aarbel
Copy link

Aarbel commented Oct 23, 2020

@jinwoo-kim-nhn any fixes for the problem ?

@bpautsch
Copy link

Any updates? I'm experiencing the same issue with an AWS S3 image that's publicly available.
Example: https://3stepsolutions.s3.amazonaws.com/assets/custom/000364/images/web/jet-ski.jpg

TUI-JS-Error

@cseriyad
Copy link

cseriyad commented Mar 25, 2021

May be this problem solved for AWS S3 bucket. you can try this.
Link : https://zyst.io/how-to-fix-aws-s3-chrome-and-safari-cors-on-images

@maccup
Copy link

maccup commented Apr 2, 2021

I have all public CORS settings in S3 and randomly getting this error, any updates? What I noticed in failed requests, there is no HTTP Request Method like GET/HEAD when it fails, no idea if Chrome DevTools doesn't show it, or it is possible to send request without method, probably not ... AWS s3 requires to have a method specified (I have GET/HEAD), maybe here is a problem?

@bpautsch
Copy link

bpautsch commented Apr 2, 2021

I have all public CORS settings in S3 and randomly getting this error, any updates? What I noticed in failed requests, there is no HTTP Request Method like GET/HEAD when it fails, no idea if Chrome DevTools doesn't show it, or it is possible to send request without method, probably not ... AWS s3 requires to have a method specified (I have GET/HEAD), maybe here is a problem?

Same here. There is nothing blocking the download of these images.
I'm using this tool in the Froala editor and they have no problem downloading and displaying images.
Not working with AWS S3 is a big problem. We're hiding this tool for now.

@Fawesum
Copy link

Fawesum commented Apr 20, 2021

Only getting this issue with Toast. Renders the entire editor unusuable. Will seek out another tool.

@maccup
Copy link

maccup commented Apr 20, 2021

Agree, I temporarily disabled the editor tool since we don't know how to solve this right now. Any ideas?

@pythobot
Copy link

pythobot commented Jun 4, 2021

I was having the same issue with Amazon S3 urls, which after setting up the bucket CORS, it was still not working.

Looks like a cache issue, so I just fixed it by adding a random parameter at the end of the url:

s3_url+'&t='+Math.random()

It seems to work well now.

@lja1018
Copy link
Contributor

lja1018 commented Jun 16, 2021

@arnaldoanez
I'm sorry for the late reply.
Thank you for suggesting a good way.

@omar-dulaimi
Copy link

Hello,

Any updates on this?

I use pre-signed urls, so setting a random query like suggested above won't work; since aws check the url to validate it's signature.

What other options do we have? (besides switching to a different image editor)

@omar-dulaimi
Copy link

It only works if you disable cache in chrome dev tools. Users don't open devtools, so that can't be a solution.

@omar-dulaimi
Copy link

On Firefox it works okay. Chrome however, it does not.

@VitaliyOnRule
Copy link

@omar-dulaimi if you can you can create proxy route on your back-end which will return the image by the required route
for example
"https://my-app.com/image-proxy?url=https://aws-image"
Or it also can be not aws issue but cloudflare.
Cloudflare also as mediator could have access control origin blockers

@omar-dulaimi
Copy link

@VitaliyOnRule I'm not sure I understand what would the proxy do in this scenario, is it going to behave like a cdn?

I currently get the pre-signed urls through the backend, just load them on the frontend in the editor.

Also, I don't use cloudflare. But we do have nginx config on our elastic beanstalk.

@VitaliyOnRule
Copy link

@omar-dulaimi with proxy you will request image from your server firstly - and will get the image hosted on aws. And you will exclude access-control-allow-origin error and will get the image for 100% because image will be requested not from the browser.
And then your server will respond on browser request with fetched image.

  1. request from chrome to you back-end - https://my-app.com/image-proxy?url=https://aws-image"
  2. request from backend to aws - https://aws-image
  3. getting image from aws and responding to chrome request with fetched image

@Ilaiwi
Copy link

Ilaiwi commented Sep 28, 2021

after digging into this and playing a bit with the source code. I found that this line here is causing the CROS issue. Providing a way to override it would solve the issue.
I am working on an external patch fix if it all went well I will post it here.
This is a temp fix thought I think definitely a way to override the image option is the optimal solution

UPDATE
patch file

diff --git a/node_modules/tui-image-editor/.DS_Store b/node_modules/tui-image-editor/.DS_Store
new file mode 100644
index 0000000..3e391de
Binary files /dev/null and b/node_modules/tui-image-editor/.DS_Store differ
diff --git a/node_modules/tui-image-editor/dist/tui-image-editor.js b/node_modules/tui-image-editor/dist/tui-image-editor.js
index 5b1f7e5..e7587ba 100644
--- a/node_modules/tui-image-editor/dist/tui-image-editor.js
+++ b/node_modules/tui-image-editor/dist/tui-image-editor.js
@@ -7231,7 +7231,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var imageOption = {
   padding: 0,
-  crossOrigin: 'Anonymous'
+  // crossOrigin: 'Anonymous'
 };
 
 /**

@KrYpTeD974
Copy link

KrYpTeD974 commented Sep 29, 2021

After debugging with Burp Suite, I think I identified the problem and found a solution. No patch should be needed.

What's the quick solution ?
Add the attribute crossorigin="anonymous" in the <img> tag that displays the image before opening it in the editor.
ie: <img src="targetUri" crossorigin="anonymous" />

Explain the issue and solution
The main issue is related to caching and how the browser sends the Origin header.

First you have to know that by default the browser does not send the Origin header when you load an image with the <img> tag that does not have the crossorigin="anonymous" attribute.
More info

What's happening is that the browser tries to load the image from the <img> tag before the image editor is opened, and the puts it into its cache.

So when you open the editor, it tries to load the image a second time, and you actually get a cached response of the first request that was made without the Origin header. Without this header, that cached response does not contain all the allow-control-* headers necessary to pass the CORS check, that's why you get the error.

You can check this, by opening Chrome's inspector with "disable cache" checked. It should work.
The previous posts that suggested to include a parameter ?t=<random_number> had the effect to bypass the browser cache, but this solution is not possible when using pre-signed urls.

So adding crossorigin="anonymous" in the img tag should solve the problem.

@DanielePalombo
Copy link

@KrYpTeD974 's solution doesn't work for me :(

@KrYpTeD974
Copy link

@DanielePalombo Could you elaborate more ? I'm pretty sure this issue can be solved with the crossorigin="anonymous" tag.
But maybe there are some subtleties to adapt in your code.

@DanielePalombo
Copy link

It doesn't work because my server makes a redirect to the source image on s3. I had to set the s3 cors configuration with my domain.

@GuanJdoJ
Copy link

@KrYpTeD974 Could you provide an example ?
In React project, my code is
const ref = React.useRef(null); const instance = new ImageEditor(ref.current, {}) //... return (<div ref={ref}/>
I don't know how to add the attribute crossorigin="anonymous" in the tag.
thx

@sergeyukhanov
Copy link

Hi. Any update on this?

@lja1018
Copy link
Contributor

lja1018 commented Apr 20, 2022

@sergeyukhanov
It has not been fixed yet. I'm sorry.

@brendon
Copy link
Contributor

brendon commented May 5, 2022

For those using Froala and who have access to the source code for the plugin (I can't remember if the plugin source code is open or not still) just add this line somewhere in the launch function after current_image_src is obtained:

if(current_image_src.indexOf('base64') === -1) {
  current_image_src = current_image_src + (current_image_src.indexOf('?') === -1 ? '?' : '&') + `timestamp=${new Date().getTime()}`
}

Won't work for signed URL's as people have mentioned, but works otherwise.

@elcatania
Copy link

elcatania commented May 13, 2022

We had the same issue with signed S3 URL. We found a workaround and preloaded the url in an Image object in the compenent implementing the editor.

const tempImage = new Image()
tempImage.crossOrigin = "Anonymous"
tempImage.src = JSON.parse(this.value).backgroundImage.src

@brendon
Copy link
Contributor

brendon commented May 15, 2022

@elcatania, did you find it worked well with Chrome?

@elcatania
Copy link

@brendon Yes it does

@brendon
Copy link
Contributor

brendon commented May 18, 2022

Thanks @elcatania, Is it the case that you've not previously had an image in the page with that same src? Otherwise I would have expected Chrome to have cached the response that didn't contain the CORS information.

@elcatania
Copy link

@brendon The issue was exactly as described previously. The image was being loaded and the cached request threw an CORS error. But the manually reloading of the image somehow fixed the issue. We still dont really know how and why it works.

@brendon
Copy link
Contributor

brendon commented May 18, 2022

Yea that's pretty strange :) Glad it works though :D

@mhamzaraja
Copy link

@elcatania How can I apply your Changes or Where do I have to add these lines?

const tempImage = new Image()
tempImage.crossOrigin = "Anonymous"
tempImage.src = JSON.parse(this.value).backgroundImage.src

sorry I don't understand I am facing the same issue and apply all solutions and it still now working. Can you please help me to resolve this issue?

Thank you

@elcatania
Copy link

@mhamzaraja basically in the component where you use the tui image editor.

For us it was inside our wrapper component in the mounted event.

const tempImage = new Image()
tempImage.crossOrigin = "Anonymous"
tempImage.src = JSON.parse(this.value).backgroundImage.src // <-- backgroundImage.src = to url to image, ignore the JSON.parse(this.value)

@mhamzaraja
Copy link

@elcatania I am implementing this in angular and on my end it's like

this.editorComponent.editorInstance.loadImageFromURL(this.data.src, 'Image').then(x => console.log(x)).catch(x => console.log(x)), 100)

and I am passing the image URL to editor instance

@mhamzaraja
Copy link

@elcatania Can you please share your code so I can check and adjust that according to my end?

@elcatania
Copy link

@mhamzaraja We do it in vuejs "mounted" event which should correspond to angulars ngAfterViewInit if i recall correctly. Do it before your 'this.editorComponent.editorInstance.loadImageFromURL'

@peyafaguerre
Copy link

Any news? Same problem here.

@YanivWein24
Copy link

I'm having the same issue when trying to load images generated by Dall-E.
KrYpTeD974 's response did not help, unfortunately.

@KrYpTeD974
Copy link

@YanivWein24 What did you try? Do you display the image before it is editable? Did you set crossorigin=anonymous on the displayed image and not the editor? Do you see the Host header being sent when the image is requested?
Do you have the problem when the browser's inspector is opened and "disabled cache" is checked?

@YanivWein24
Copy link

@KrYpTeD974 I'm generating images using different text-to-image AI models, and then the users can select the images they liked and start editing them using the image editor (on a new page).
I also display the list of selected images above the editor component.

It is working fine most of the time, but it doesn't load images generated by DALL-E (every single time!).
I'm trying to load the images using loadImageFromUrl and receiving CORS errors (the images are showing just fine in the list above the editor).

I tried to set crossorigin=anonymous on the displayed images and it didn't change anything.
The issue occurs regardless of the inspector's state (open/close) and cache in the browser (disabled/enabled).

What I ended up doing was taking the images I received from DALL-E and uploading them to 3rd party service before redirecting to the image editor. and instead of using the original images URLs I use the URLs I receive when uploading the images.

CORS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests