Habe ich nicht genug geschlafen oder was? Dieser folgende Code
var frame=document.getElementById("viewer");
frame.width=100;
frame.height=100;
var ctx=frame.getContext("2d");
var img=new Image();
img.src="http://www.ansearch.com/images/interface/item/small/image.png"
img.onload=function() {
// draw image
ctx.drawImage(img, 0, 0)
// Here's where the error happens:
window.open(frame.toDataURL("image/png"));
}
wirft diesen Fehler:
SECURITY_ERR: DOM Exception 18
Das sollte auf keinen Fall funktionieren! Kann das bitte jemand erklären?
In den specs heißt es:
Wann immer die toDataURL () -Methode eines Canvas-Element, dessen Origin-clean-Flag auf false gesetzt ist, wird die Methode .__ aufgerufen. muss eine SECURITY_ERR-Ausnahme auslösen.
Wenn das Image von einem anderen Server kommt, glaube ich nicht, dass Sie toDataURL () verwenden können.
Cross-Origin-Attribut für die Bildobjekte setzen, die für mich bearbeitet wurden (ich habe fabricjs verwendet)
var c = document.createElement("img");
c.onload=function(){
// add the image to canvas or whatnot
c=c.onload=null
};
c.setAttribute('crossOrigin','anonymous');
c.src='http://google.com/cat.png';
Für diejenigen, die fabricjs verwenden, finden Sie hier den Patch für Image.fromUrl
// patch fabric for cross domain image jazz
fabric.Image.fromURL=function(d,f,e){
var c=fabric.document.createElement("img");
c.onload=function(){
if(f){f(new fabric.Image(c,e))}
c=c.onload=null
};
c.setAttribute('crossOrigin','anonymous');
c.src=d;
};
Wenn das Image auf einem Host gehostet wird, für den Access-Control-Allow-Origin oder Access-Control-Allow-Credentials festgelegt ist, können Sie Cross Origin Resource Sharing (CORS) verwenden. Siehe hier (das crossorigin-Attribut) für weitere Details.
Ihre andere Option besteht darin, dass Ihr Server über einen Endpunkt verfügt, der ein Image abruft und bereitstellt. (zB http: // Ihr_Host/Endpunkt? url = URL ) Der Nachteil dieses Ansatzes ist die Latenzzeit und theoretisch unnötiges Abrufen.
Wenn es alternative Lösungen gibt, wäre ich daran interessiert, von ihnen zu hören.
Anscheinend gibt es eine Möglichkeit, das zu verhindern, wenn Image-Hosting die folgenden HTTP-Header für die Image-Ressourcen und den Browser bereitstellt, die CORS unterstützen:
zugriffskontrollgenehmigung-Ursprung: * Zugriffskontrollgenehmigungsanmeldeinformationen: wahr
Es ist hier angegeben: http://www.w3.org/TR/cors/#use-cases
Endlich habe ich die Lösung gefunden. Fügen Sie einfach die crossOrigin
als dritten Parameter in fromURL
func hinzu
fabric.Image.fromURL(imageUrl, function (image) {
//your logic
}, { crossOrigin: "Anonymous" });
Ich konnte es so machen, dass es funktioniert:
Schreiben Sie dies in die erste Zeile Ihres .htaccess
auf Ihrem Quellserver
Header add Access-Control-Allow-Origin "*"
Gehen Sie dann beim Erstellen eines <img>
-Elements folgendermaßen vor:
// jQuery
var img = $('<img src="http://your_server/img.png" crossOrigin="anonymous">')[0]
// or pure
var img = document.createElement('img');
img.src='http://your_server/img.png';
img.setAttribute('crossOrigin','anonymous');
Ich hatte das gleiche Problem und alle Bilder werden in derselben Domäne gehostet ... Wenn also jemand das gleiche Problem hat, habe ich das Problem gelöst:
Ich hatte zwei Buttons: eine zum Erzeugen der Leinwand und eine andere zum Erzeugen des Bildes aus der Leinwand. Es hat nur für mich funktioniert und es tut mir leid, dass ich nicht weiß warum, als ich den Code auf den ersten Button geschrieben habe. Wenn ich also klicke, generieren Sie gleichzeitig die Leinwand und das Bild ...
Ich habe immer dieses Sicherheitsproblem, wenn die Codes unterschiedliche Funktionen hatten ... = /
Sie können keine Leerzeichen in Ihre ID einfügen
Update
Meine Vermutung ist, dass sich das Image auf einem anderen Server befindet als auf dem Sie das Skript ausführen. Ich konnte Ihren Fehler bei der Ausführung auf meiner eigenen Seite duplizieren. Der Fehler funktionierte jedoch in dem Moment, in dem ich ein auf derselben Domain gehostetes Image verwendete. Es ist also sicherheitsbezogen - platzieren Sie das Image auf Ihrer Website. Weiß jemand warum das so ist?
Ich verwende fabric.js und könnte dies durch Verwendung von toDatalessJSON anstelle von toDataURL beheben:
canvas.toDatalessJSON({ format: 'jpeg' }).objects[0].src
Edit: Nevermind. Dies führt dazu, dass nur das Hintergrundbild in JPG exportiert wird, ohne dass die Zeichnung oben angezeigt wird. Es war also nicht ganz nützlich.
Wenn Sie nur einige Bilder auf einer Leinwand zeichnen, stellen Sie sicher, dass Sie die Bilder aus derselben Domäne laden.
www.example.com unterscheidet sich von example.com
Stellen Sie daher sicher, dass Ihre Bilder und die URL, die Sie in Ihrer Adressleiste haben, gleich sind.