The Cross-Origin Resource Sharing (CORS) protocol imposes security restrictions on certain KeyLines functions.
For example, you may want to reference an image that doesn't originate from the same domain as the KeyLines library file. Your browser will mark it as insecure and prevent the image from being loaded. KeyLines will attempt to load the image again with the crossorigin HTML attribute set. You can use the KeyLines.corsAdapter() function to change the value of the attribute. If it still cannot load the image, it will mark it as missing and throw a SecurityError exception.
To use KeyLines in WebGL mode, you should run it from a web server, not a file system.
To make sure your images display properly, do one of the following:
Note: You can only use this solution if you can configure the web server that’s providing the resources. If they’re coming from a third-party server, you'll need to Proxy the resources.
To give KeyLines access to the resource's contents, you need to configure the remote resource’s web server to set an Access-Control-Allow-Origin header in its response.
For example, if KeyLines was at http://www.example.com/vendor/keylines, in the headers returned with the resources, you’d set:
Access-Control-Allow-Origin: http://www.example.com
Security policies can also sometimes restrict loading of inline images. From version 5.0, KeyLines loads both asset and placeholder images inline as data URI images.
To resolve this you can permit image elements to load data URIs, which should maintain the security of your application while allowing KeyLines to function:
<meta http-equiv="Content-Security-Policy" content="img-src 'self' data:" />
You can use the web server (that contains the KeyLines library file) as a proxy for resources, so you’re no longer requesting them from a different domain. How you do this depends on which web server you’re using, but the basic approach is:
This caching example is based on the Express web framework. To make it simpler, we’ve taken out the error-handling code:
app.get('/images/:name', function (req, res) {
// look in store for picture
var name = req.params.name;
var filename = path.join(picdirectory, name + '.jpg');
fs.exists(filename, function (exists) {
// if we have cached the file already then just pipe it back to the client
if (exists) {
fs.createReadStream(filename).pipe(res);
}
else {
var outstream = fs.createWriteStream(filename, {flags : 'w'});
var url = 'http://www.example.com/path/to/images/' + name;
//now stream this into the file
var imagestream = request.get({uri:url});
imagestream.pipe(outstream);
//when finished just pipe back to client
outstream.on('close', function () {
fs.createReadStream(filename).pipe(res);
});
}
});
});