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

Use of blob responseType in ImageLoader. #9826

Closed
3 of 12 tasks
jee7 opened this issue Oct 5, 2016 · 11 comments
Closed
3 of 12 tasks

Use of blob responseType in ImageLoader. #9826

jee7 opened this issue Oct 5, 2016 · 11 comments

Comments

@jee7
Copy link
Contributor

jee7 commented Oct 5, 2016

Description of the problem

The ImageLoader sets the response type of XHRLoader to blob. This causes a problem with Chrome (53.0.2785.116 m) and running the script from the local filesystem, while fetching textures from a web server. It seems to me that this is a security consideration of Chrome. The closest info I found is this, but that does not seem exactly about that. In Firefox (49.0.1) there is no issue.

For me this functionality is important, because I'm using Three.js to teach CG and the students should not worry about web servers. Also I'd guess there are people, who want to prototype some things with Three.js and not set up a web server to do that.

I made the responseType to be a parameter of the ImageLoader (and the TextureLoader) and with arraybuffer type there is no problem: see image.
The top row uses the r80 implementation with blob and the bottom row uses arraybuffer response type. With the arraybuffer I base64 encode it and set it as a data URL to the image.

You can also see that actually the arraybuffer seems a lot faster then the blob implementation. This seems to be that for some reason Chrome knows how to cache the former, but not the latter.
If the script is in a web server: see image.
With no caching the arraybuffer seems marginally faster with the texture I used: see image.

Live example (download the file, the modified lib and open it from the local filesystem to see errors):
http://tume-maailm.pri.ee/ylikool/ComputerGraphics-2015/other/uv-test/index-loadingTest.html
The no-cache version:
http://tume-maailm.pri.ee/ylikool/ComputerGraphics-2015/other/uv-test/index-loadingTest-noCache.html

I did this with r80, but r81 seems to have the same issue.

Should I create a fork and PR with the responseType as a configurable value of the TextureLoader and ImageLoader?

Might also be related to #9824, as, like I noticed, the request with blob response type does not cache the response in Chrome. So it will send new requests until the first one gets back and Three.js' own cache kicks in (maybe?).

Three.js version
  • Dev
  • r81
  • r80
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS
Hardware Requirements (graphics card, VR Device, ...)

No special requirements.

@calrk
Copy link
Contributor

calrk commented Oct 5, 2016

Is the problem you are getting a Cross-Origin error?

The Image/Texture loader works using a blob for onProgress events, as implemented here:
#8904

@jee7
Copy link
Contributor Author

jee7 commented Oct 6, 2016

It's not quite a cross-origin error, because loading an image from another domain works well. It is when I try to load the image from a script in the local filesystem file://..../script.html and the image is in a web server http://.../image.png. In that case Chrome creates this blob:null/hash thing as the image.src with URL.createObjectURL.

I get that the onProgress event might not work if using arraybuffer. So the onProgress isn't currently working for BinaryTextureLoader and CompressedTextureLoader either?

Proposal is that this could be a configurable parameter of the TextureLoader and ImageLoader. So the user can pick, which is more important: loading files to a local script or having the onProgress event.

@mrdoob
Copy link
Owner

mrdoob commented Oct 7, 2016

Should I create a fork and PR with the responseType as a configurable value of the TextureLoader and ImageLoader?

Yes please! 😊

jee7 added a commit to jee7/three.js that referenced this issue Oct 9, 2016
…der and TextureLoader. Added constants for ResponseType.Blob and ResponseType.ArrayBuffer. Implemented arraybuffer response parsing in ImageLoader.
@jee7
Copy link
Contributor Author

jee7 commented Oct 9, 2016

The Image/Texture loader works using a blob for onProgress events

I tried the onProgress events and they seemed to work with arraybuffer as well.

@mrdoob
Copy link
Owner

mrdoob commented Oct 15, 2016

#9834

@mrdoob
Copy link
Owner

mrdoob commented Oct 15, 2016

For me this functionality is important, because I'm using Three.js to teach CG and the students should not worry about web servers. Also I'd guess there are people, who want to prototype some things with Three.js and not set up a web server to do that.

Are you teaching the students to load chrome using --allow-files-access-from-files or something?

@fraguada
Copy link
Contributor

Firing up a local web server is trivial: https://gist.github.com/willurd/5720255

@jee7
Copy link
Contributor Author

jee7 commented Oct 15, 2016

Are you teaching the students to load chrome using --allow-files-access-from-files or something?

No. Just open the HTML file in the browser. Yes, the --allow-files-access-from-files is a possibility, but not necessary, as the images are already hosted online.

Firing up a local web server is trivial: https://gist.github.com/willurd/5720255

Not for everyone.

@mrdoob
Copy link
Owner

mrdoob commented Oct 17, 2016

Hmm...

I worry that this workaround may stop working eventually. In my experience, is not good to "fight" around browsers... Also, Chrome's #2 starred bug is about this: https://bugs.chromium.org/p/chromium/issues/detail?id=47416

Until they address that, I think I would suggest using Firefox instead.

@jee7
Copy link
Contributor Author

jee7 commented Oct 18, 2016

Yeah, you are probably right that it won't last forever. But the Chrome's bug is not actually about this. I am not trying to load any local files, but cross-origin files from a web server and that works nicely with the loader.setCrossOrigin and a corresponding .htaccess file.
The problem I have is with the blob data type. I'm not that familiar with this, but for some reason it works differently for local scripts loading blobs from the web.

What I ended up doing was I commented out the URL.revokeObjectURL( image.src ); in the r81, which I sent to the students. Everything seemed to work then, as I mentioned in the PR review.

There is also that browser caching to check out. I saw that you closed the other issue. I was wondering about that, does the Three.js cache work after a texture has been loaded? So if one were to enable the cache and then load many big and same textures as blobs, then Chrome would still send many requests for them?
With arraybuffer Chrome seemed to cache the requests... We should test if it would send only one request per URL and wait for that response. Or spam the same URL with requests as it seemed to do with the blob type.

@mrdoob
Copy link
Owner

mrdoob commented Dec 22, 2016

#10439

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

No branches or pull requests

4 participants