Cross-Origin Resource Sharing bypass

I was coding some Three.js scenes earlier and encountered the following error in Chrome (v27):

Cross-origin image load denied by Cross-Origin Resource
Sharing policy

It happened when I was trying to load an image from a file to use as a texture for a material I wanted to apply to a mesh.  Basically, I wanted my plane to have a grass texture.

THREE.ImageUtils.loadTexture('images/grass.jpg')

Even though both the .html and the .jpg were in the same location (both local, same folder) the error occurred.  Whilst the error, then, makes no sense, it is however ‘working as intended’.  This is, it seems, a security ‘feature’ that is implemented in many browsers, not just Chrome.

Now, I didn’t want to downgrade the security of my browser by launching it as suggested by some:

chrome --allow-file-access-from-files

and I didn’t want to fire up a web server of any kind just for one placeholder texture, as suggested by others:

How to run things locally

Basically, I was in a lazy mood and just wanted a simple security bypass.  🙂  If you do too then the following approach may be of interest…

In essence, we’re going to turn a binary image into text, store that text in a .js file, and then link that external javascript file into our project page.

var grass = new Image();
grass.src = "data:image/jpeg;base64...";
  • save the document in your project folder somewhere: “images/grassData.js”
  • link to that external javascript file in the <head> of your project page:
http://images/grassData.js
  • create a new Three.js texture using that image element:
var grassTexture = new THREE.Texture(grass);
grassTexture.wrapS = THREE.RepeatWrapping;
grassTexture.wrapT = THREE.RepeatWrapping;
grassTexture.repeat.x = grassTexture.repeat.y = 32;
grassTexture.needsUpdate = true;
  • add the texture to a mesh:
var terrain = new THREE.Mesh(
  new THREE.PlaneGeometry(x,y,x*res,y*res),
  new THREE.MeshLambertMaterial({ map: grassTexture });
);

…and you’re done.  No error.  🙂

Note that this is not intended as a permanent solution to the ‘problem’.  It’s a quick hack to save you some time.  When you deploy your website you want to make sure you’re loading images into textures the normal way to take advantage of caching and smaller file sizes.

Also note that some browsers have rather small limits (32k-ish) on the size of Data URIs, but Chrome/Safari don’t seem to care how large it is.  My grass data was 2.3MB in size and loaded without a hitch.  Just something to look out for if you’re using one of the other browsers.

Enjoy!

Advertisement

6 thoughts on “Cross-Origin Resource Sharing bypass

  1. That converter has a 32kB limit but if your image is only small it will work just fine as well. I’m glad you liked the hack.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s