2011-01-12 6 views
15

Ich habe eine Website unter pixie.strd6.com und Bilder gehostet über Amazon S3 mit einem CNAME für images.pixie.strd6.com.HTML5 Canvas getImageData und die gleiche Herkunft Richtlinie

Ich möchte in der Lage sein, diese Bilder zu einem HTML5 Leinwand zu ziehen und die getImageData Methode aufrufen, aber es wirft Error: SECURITY_ERR: DOM Exception 18

ich window.domain = "pixie.strd6.com" versucht haben, Einstellung, aber das hat keine Wirkung.

Zusätzlich $.get("http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982", function(data) {console.log(data)}) wirft auch einen Fehler: XMLHttpRequest cannot load http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982 . Origin http://pixie.strd6.com is not allowed by Access-Control-Allow-Origin.

Idealer HTML5-Canvas würde nicht blockieren getImageData von Sub-Domains aufrufen. Ich habe in S3 nachgesehen, einen Access-Control-Allow-Origin-Header festzulegen, aber nicht erfolgreich.

Jede Hilfe oder Workarounds werden sehr geschätzt.

+34

Diese gleichen Ursprung Politik ist das Dümmste, was verwenden werden je . Wenn ich ein bösartiges Stück JavaScript bin und ich schädliche Daten laden will, werde ich einfach ein beliebiges Skript-Tag in die Seite einfügen, nicht "s3kri7 c0mm4nd5" aus Bilddaten lesen. Die einzigen Leute, die Bilddaten lesen möchten, sind clientseitige Entwickler. Was das Stehlen von "streng geheimen Bilddaten" von einem VPN betrifft, ist das Keylogging sehr viel verheerender, wenn Ihre Site bereits xssd ist. All dieser "Schutz" dient dazu, legitime Entwickler zu erschweren, die versuchen, JavaScript dazu zu bringen, die einfachsten Aufgaben zu erledigen. –

+7

Die SOP schützt hier vor einem legitimen Angriffsvektor.Angenommen, Sie haben ein privates Fotoalbum auf einer Foto-Sharing-Site (oder überprüfen Sie Bilder, die in Ihrem Online-Banking gespeichert sind): ohne schmutzigen Canvas-Schutz * hätte jede Seite im Web *, die Sie besuchen, die Bilder URL und Sie waren angemeldet, weil Anfragen, die von '' Tags ** gesendet wurden, Ihre Cookies verwenden **. Das Problem hier ist nicht kompromittiert XSS'd Websites; Das Problem ist, dass * jede Seite im Web * mithilfe Ihrer Authentifizierungscookies Bilder auf einer Zeichenfläche abrufen und lesen kann. – apsillers

+2

** tl; dr: ** So wie es jetzt aussieht, kann jede domänenübergreifende Website * Ihre authorisierten Bilder (private Fotos, Scheckbilder usw.) in einem '' Tag anzeigen, aber dank der SOP, sie können den Inhalt dieser Bilder in einer Zeichenfläche nicht * lesen *, um sie zB auf einem Server zu speichern. – apsillers

Antwort

6

Amazon recently announced CORS support

We're delighted to announce support for Cross-Origin Resource Sharing (CORS) in Amazon S3. You can now easily build web applications that use JavaScript and HTML5 to interact with resources in Amazon S3, enabling you to implement HTML5 drag and drop uploads to Amazon S3, show upload progress, or update content. Until now, you needed to run a custom proxy server between your web application and Amazon S3 to support these capabilities.

How to enable CORS

1

Dieses Verhalten ist By-Design. Gemäß der HTML5-Spezifikation ist es verschmutzt, sobald Sie ein Bild mit Ursprungsüberschrift auf eine Arbeitsfläche zeichnen, und Sie können die Pixel nicht mehr lesen. Origin-Abgleich vergleicht das Schema, vollständig qualifizierten Host und in Nicht-IE-Browsern den Port.

+0

Die Problemumgehung besteht also darin, einen Proxy über meinen Webserver einzubinden? –

+4

Ja, der Servercode für die Bilder wird funktionieren, aber es ist traurig, dass wir uns auf etwas verlassen müssen, das nicht benötigt wird. Sie sollten zumindest bereichsübergreifende Richtlinien über eine XML-Datei auf dem Zielserver implementieren, wie dies mit Flash geschehen ist. – Omiod

3

Eine mögliche Lösung besteht darin, nginx als Proxy zu verwenden. Hier erfahren Sie, wie Sie URLs konfigurieren, die zu http://pixie.strd6.com/s3/ weitergeleitet werden, um sie an S3 weiterzuleiten, aber der Browser kann immer noch glauben, dass er nicht domänenübergreifend ist.

location /s3/ { 
    proxy_pass http://images.pixie.strd6.com/; 
} 
2

Vor kurzem stieß ich auf $.getImageData, von Max Novakovic. Die Seite enthält ein paar nette Demos zum Abrufen und Ausführen von Flickr-Fotos sowie einige Codebeispiele.

Sie können ein Bild in JavaScript-manipulierbarer Form von einer beliebigen Site abrufen. Es funktioniert, indem ein Skript an die Seite angehängt wird. Das Skript fordert dann das Bild von einem Google App Engine-Server an. Der Server ruft das angeforderte Bild ab und leitet es in base64 konvertiert an das Skript weiter. Wenn das Skript die base64 empfängt, übergibt es die Daten an einen Rückruf, der sie dann auf eine Zeichenfläche zeichnen und damit beginnen kann, damit umzugehen.

2

In der Vergangenheit erlaubte Ihnen Amazon S3 nicht, die HTTP-Header access-control-allow-origin und access-control-allow-credentials zu ändern oder hinzuzufügen, sodass es möglicherweise besser war, zu einem anderen Dienst wie Rackspace zu wechseln Cloud-Dateien oder ein anderer Dienst, der dies tut.

Hinzufügen oder die HTTP-Header wie folgt ändern:

access-control-allow-origin: [your site] 
access-control-allow-credentials: true 

http://www.w3.org/TR/cors/#use-cases Siehe für weitere Informationen.

Mit einem Dienst, mit dem Sie die HTTP-Header ändern können, wird das gleiche Ursprungsproblem vollständig gelöst.

3

Wenn Sie PHP verwenden, können Sie so etwas wie:

function fileExists($path){ 
     return (@fopen($path,"r")==true); 
    } 
    $ext = explode('.','https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg'); 
    if(fileExists('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg')){ 
     $contents = file_get_contents('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg'); 
     header('Content-type: image/'.end($ext)); 
     echo $contents; 
    } 

Und das Bild zugreifen, indem Sie die PHP-Datei, wie wenn die Datei generateImage.php genannt wird Sie <img src="http://GENERATEPHPLOCATION/generateImage.php"/> und das externe Bild machen kann uRL kann ein get Parameter für die Datei sein

2

Für Leute, die S3 nicht verwenden, können Sie versuchen, einen Bildproxy zu erstellen, der die Bilddatei codiert und sie in ein JSON-Objekt einfügt.

Dann können Sie JSONP verwenden, das Cross-Domain unterstützt, um das JSON-Objekt abzurufen und die Bilddaten an img.src zuzuweisen.

Ich schrieb einen Beispielcode des Bild-Proxy-Servers mit Google App Engine. https://github.com/flyakite/gae-image-proxy

JSON Objekt zurückgibt, in dem Format, wie diese

{ 
    'height': 50, 
    'width' : 50, 
    'data' : 'data:image/jpeg;base64,QWRarjgk4546asd...QWAsdf' 
} 

'Daten' die Bilddaten in Base64-Format. Ordne es einem Bild zu.

img.src = result.data; 

Das Bild ist jetzt "sauber" für Ihre Leinwand.

2

Um Ihre S3-Bucket Berechtigungen zu bearbeiten:

1) Melden Sie sich an der AWS Management Console in und öffnen Sie die Amazon S3-Konsole bei https://console.aws.amazon.com/s3/

2) In der Eimer Liste, öffnen Sie den Eimer, dessen Eigenschaften Sie wollen anzuzeigen, und klicken Sie zwischen den Tags hinzuzufügen in "add CORS-Konfiguration"

amazon-screen-shot

3) schreiben Sie die Regeln, die Sie bereit sind, <CORSConfiguration>

<CORSConfiguration> 
    <CORSRule> 
    <AllowedOrigin>*</AllowedOrigin> 
    <AllowedMethod>GET</AllowedMethod> 
    <MaxAgeSeconds>3000</MaxAgeSeconds> 
    <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
</CORSConfiguration> 

Sie können mehr über Regeln lernen: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

4) Geben Sie crossorigin = ‚anonym‘ auf dem Bild, das Sie in Ihrer Leinwand