I am trying to load an image into a canvas element and later pull the data out in toDataURL().
I have my site running with Ruby on Rails 2.3
I have my images serving from aws s3. I have setup cors:
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
I have a canvas element:
<canvas id="explain_canvas"></canvas>
Okay, so some background. I was originally trying this with code like this where drawing_image is just a url to the image.
var outlineImage = new Image();
outlineImage.crossOrigin = '';
outlineImage.src = drawing_image;
outlineImage.onload = function() {
var canvas = document.getElementById('explain_canvas');
var context = canvas.getContext("2d");
context.drawImage(outlineImage, 10, 10, 600, 150);
}
But that was not sending the origin header. So I thought I'd try an ajax call via jquery
var outlineImage = new Image();
$(outlineImage).attr('crossOrigin', '');
$.ajax({
type: 'get',
url : drawing_image,
contentType: 'image/png',
crossDomain: 'true',
success: function() {
$(outlineImage).attr("src", drawing_image);
},
error: function() {
console.log('ah crap');
}
});
outlineImage.onload = function() {
var canvas = document.getElementById('explain_canvas');
var context = canvas.getContext("2d");
context.drawImage(outlineImage, 10, 10, 600, 150);
}
But still no luck. Am I mistaken? Should that jquery ajax send the origin header?
I look at the request header and this is what I get on the image:
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:em2-images.s3.amazonaws.com
Referer:http://localhost:3000/courses/18/quizzes/22/take
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11
And the jquery errors with this:
XMLHttpRequest cannot load http://em2-images.s3.amazonaws.com/EM2_LF_A_5_item6.png. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.
ah crap
What is weird to me is the jquery states the origin, yet it is not in the request header.
This stackoverflow question here states he wants to remove the origin header. Well he is doing the same kind of call I am with jquery ajax and getting it. Any ideas why I am not?
If I reload the page, it grabs the cached image and loads it fine (with the origin header mind you) and calls toDataURL() just fine. After I clear the cache it again won't work that first load until the image is cached.
I started wondering if Rails was doing something to it, but I don't see how it would since this is an ajax call. But who knows, anyone know if Rails could do this?
I have tried this in several browsers on different platforms. Chrome, Firefox, Safari, IE 9 & 10. On my Mac, PC, and iPhone. No dice on any of them.
-Thanks-
The reason for that is, as mentioned earlier in this answer, browsers always send the Origin header in all POST , PUT , PATCH , and DELETE requests. Also, for completeness here and to be clear: For navigations, browsers send no Origin header.
To enable cross-origin access go to Tools->Internet Options->Security tab, click on “Custom Level” button. Find the Miscellaneous -> Access data sources across domains setting and select “Enable” option.
The Origin spec indicates that the Origin header may be set to "null". This is typically done when the request is coming from a file on a user's computer rather than from a hosted web page. The spec also states that the Origin may be null if the request comes from a "privacy-sensitive" context.
After much brain smashing, I have figured out why my browser isn't sending the origin header.
First a little background. This is for an LMS and is part of a quiz. When the teacher authors the quiz, they add the question text and an image to go into the a drawing canvas for students to explain their answer with a drawing.
As you can guess, that image gets loaded first. It is hidden from the students view, and I grab the src url off that image and try to put it into the canvas element using the javascript.
Well the problem with that is the first time the image is loaded, it is not loaded with the crossorigin attribute. Thus no origin header. And by the time the canvas element is trying to load the image, it is cached without having the origin header in there. And when it tries to get cors going it barfs. Seems to me like maybe this is a bug that all browsers need to fix. But perhaps not.
So in a nut shell, when doing cors, make sure the first load of an image is with a crossorigin attribute to get the origin header included. dur me...
Yup, time for a refactor...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With