2013-01-09 1 views
16

Sto provando a caricare un'immagine in un elemento canvas e successivamente estrarre i dati inDataURL().tutti i miei browser non stanno inviando l'intestazione di origine

ho il mio sito in esecuzione con Ruby on Rails 2.3

ho le mie immagini servire AWS s3. Ho cors di impostazione:

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

Ho un elemento di tela:

<canvas id="explain_canvas"></canvas> 

Okay, così alcuni retroscena. Inizialmente lo stavo provando con un codice come questo in cui drawing_image è solo un URL dell'immagine.

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); 
} 

Ma questo non stava inviando l'intestazione di origine. Così ho pensato di provare una chiamata Ajax 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); 
} 

Ma ancora senza fortuna. Mi sbaglio? Dovrebbe quel jquery ajax inviare l'intestazione di origine?

Guardo l'intestazione della richiesta e questo è ciò che ottengo sull'immagine:

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 

E jQuery errori con questo:

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 

Ciò che è strano per me è la stati jQuery l'origine, eppure non è nell'intestazione della richiesta.

Questa domanda stackoverflow here indica che desidera rimuovere l'intestazione di origine. Beh, sta facendo lo stesso tipo di chiamata con jquery ajax e ricevendolo. Qualche idea sul perché io non sia?

Se ricarico la pagina, acquisisce l'immagine memorizzata nella cache e la carica correttamente (con l'intestazione di origine che si occupa di te) e chiama a destraDataURL(). Dopo aver svuotato la cache, non funzionerà di nuovo prima che l'immagine venga memorizzata nella cache.

Ho iniziato a chiedermi se Rails stava facendo qualcosa, ma non vedo come sarebbe dato che si tratta di una chiamata ajax. Ma chi lo sa, qualcuno sa se Rails potrebbe fare questo?

Ho provato questo in diversi browser su piattaforme diverse. Chrome, Firefox, Safari, IE 9 & 10. Sul mio Mac, PC e iPhone. Nessun dado su nessuno di essi.

-Thanks-

risposta

28

Dopo aver infranto molto cervello, ho capito perché il mio browser non invia l'intestazione provenienza.

Prima un po 'di background. Questo è per un LMS e fa parte di un quiz. Quando l'insegnante scrive il quiz, aggiunge il testo della domanda e un'immagine per entrare nella tela del disegno affinché gli studenti possano spiegare la loro risposta con un disegno.

Come puoi immaginare, quell'immagine viene caricata per prima. È nascosto dalla vista studenti, e prendo l'URL src da quell'immagine e provo a inserirlo nell'elemento canvas usando javascript.

Bene, il problema è che la prima volta che l'immagine viene caricata, non viene caricata con l'attributo crossorigin.Quindi nessuna intestazione di origine. E quando l'elemento canvas tenta di caricare l'immagine, viene memorizzata nella cache senza avere l'intestazione di origine. E quando cerca di ottenere il cors di andare avanti. Mi sembra che forse questo è un bug che tutti i browser devono risolvere. Ma forse no.

Quindi, in un guscio di dado, quando si esegue cors, assicurarsi che il primo caricamento di un'immagine sia con un attributo crossorigin per includere l'intestazione di origine. me mo ...

Yup, il tempo per un refactoring ...

+2

Grazie! Sono riuscito a ovviare a ciò aggiungendo un piccolo attributo 'GET' alla cache nell'url una volta che sapevo cosa stava succedendo. – user1618143

+1

Devi aggiungere qualcosa per quelli ancora bloccati. La tua risposta è corretta, ma al momento di ottenere le risorse memorizzate nella cache, quindi quella stessa immagine una seconda volta, ha rimosso l'intestazione di origine. Quindi, se hai bisogno di memorizzare nella cache un'immagine, tenerla memorizzata in javascript e non provare a richiederla di nuovo. Stavo scoprendo che il mio tentativo di essere efficiente stava causando errori sugli elementi della cache. –

+0

Ah, amico! Mi hai salvato venerdì! Questo comportamento è piuttosto ingombrante. –

3

stavo ottenendo questo errore CORS, e nel server terminare l'intestazione origine non era stato inviato.

Il problema per me era che avevo impostato crossOrigin = Anonymous nel mio tag immagine. Rimozione che ha risolto il problema per me, e l'errore CORS era sparito.