Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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-

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
102 views
Welcome To Ask or Share your Answers For Others

1 Answer

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...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...