Reputation: 13206
I keep getting the following error for my AngularJS application hosted on Heroku:
Access to Image at 'https://d15790c7fypqrz.cloudfront.net/attachments/product_template_pictures/images/000/490/265/grid/832816_122.png' from origin 'http://.herokuapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://.herokuapp.com' is therefore not allowed access.
How do I resolve it? This is the code which does the base64 conversion:
function createBase64Property(product, callback, outputFormat) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(product, dataURL);
};
img.src = product.imageUrl;
if (img.complete || img.complete === undefined) {
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
img.src = product.imageUrl;
}
}
My web.js configuration is as follows:
var gzippo = require('gzippo');
var express = require('express');
var morgan = require('morgan');
var cors = require('cors')
var app = express();
app.use(morgan('dev'));
app.use(gzippo.staticGzip(__dirname));
app.use(cors({credentials: true, origin: true}));
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.listen(process.env.PORT || 5000);
Upvotes: 0
Views: 2312
Reputation: 529
Ok, there is a tricky way of bypassing CORS in this situation. If your angular code is deployed on a node server, you can proxy your image URL. You define a custom route handled by node which will be local.
Using grunt
You'll need to add grunt-connect-proxy
https://github.com/drewzboto/grunt-connect-proxy
After adding it to your grunt config, you have to write your proxy middleware:
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
open: true,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect().use(
'/app/styles',
connect.static('./app/styles')
),
connect.static(appConfig.app)
];
}
}
},
test: {
options: {
port: 9001,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect.static('test'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect.static(appConfig.app)
];
}
}
},
dist: {
options: {
open: true,
base: '<%= yeoman.dist %>'
}
},
proxies: [
{
context: '/outsides-images',
host: 'd15790c7fypqrz.cloudfront.net/',
https: true,
}
]
},
Using gulp
I'll show you an example using gulp for setting up the server (I know it's not a perfect solution, but you can see the pattern):
import proxy from 'http-proxy-middleware';
import gulp-connect from 'gulp-connect';
const imagesServiceProxy = proxy('/outsides-images', {
target: 'https://d15790c7fypqrz.cloudfront.net/',
changeOrigin: true,
logLevel: 'debug',
});
gulp.task('serve', () => {
connect.server({
port: 3000,
root: [ './dest' ],
livereload: false,
middleware: (connect, opt) => {
return [
imagesServiceProxy,
historyApiFallback(),
];
},
});
});
This snippet is in ES6, and I setup the server with gulp-connect
.
Now, in your AngularJS/HTML code, when you fetch the image, use the proxy URL, something like that:
/outside-images/attachments/product_template_pictures/images/000/490/265/grid/832816_122.png
I don't know how you setup your server, but I hope this answer will give you a hint about bypassing CORS.
Upvotes: 1