简体   繁体   中英

Tainted canvas for CDN Instagram photos / videos. CORS not working?

[GOAL]

My main goal is allow users to ZIP and download all Instagram loaded images in elements using only modern browser resources. I'm currently using JSZip lib that accepts files as base64 data and binary data. To achieve this, I need to access raw data via tag and getImageData() stuff.

[BACKGROUND]

Instagram API provides a set of recent images that I need via API endpoint in:

https://api.instagram.com/v1/tags/snow/media/recent. 

Instagram specify some cross-origins policies in:

https://api.instagram.com/crossdomain.xml

Instagram API serves files url in CDN fashion, resulting in images address like these:

http://scontent-a.cdninstagram.com/hphotos-xaf1/outbound-distilleryimage8/t0.0-17/OBPTH/57dc39f0a10c11e3a9af0eddfe5726fc_6.jpg

[PROBLEM] - canvas.toDataURL

I've already try this kind of solution:

<HTML>
<canvas id="canvas"></canvas>
<HTML>

<SCRIPT>
var canvas = $("#canvas1)[0];
var ctx = canvas.getContext('2d');

var img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'http://scontent-b.cdninstagram.com/hphotos-xfp1/outbound-distilleryimage2/t0.0-17/OBPTH/2d160152a10b11e39df312c88b6315b6_6.jpg'
img.onload = function(x) {
    ctx.drawImage(img, 0, 0);
    canvas.toDataURL("image/jpg"); Raise the following error:
}
<SCRIPT>

*XMLHttpRequest cannot load http://scontent-b.cdninstagram.com/hphotos-xfp1/outbound-distilleryimage2/t0.0-17/OBPTH/2d160152a10b11e39df312c88b6315b6_6.jpg?_t=11234. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8084' is therefore not allowed access*

[RELATED]

  1. It looks like crossdomain.xml is not related to content served by CDN. So, I'm stucked in tainted canvas warning when I try to call getImageData from canvas I rendered the Image

  2. Specifing img.crossOrigin = 'Anonymous' before img.src attribute does not affect the results.

  3. Right click on image in browser allows me download the current rendered image from Instagram CDN. Strange?

  4. It doesn't seem that CDN allows JSONP requests to get the image content. (callback parameter to image url is not called). I've tried with jQuery ajax.

  5. JSZip allows files in base64 format or even binary data, via Uint8Array. I've already tried a XMLHttpRequest to download binary image to CDN but got the same cross-oringin warning, cancelling the request.

Instagram allows users to download photos, but what you are trying to do is zip the contents of a canvas via javascript. This isn't allowed by design by since your javascript code may have a security issue in ZIP-ing up the bits (buffer overflows, etc), causing security concerns for the users. The solution is to wither ask instagram CDN on amazon to include these lines , since they are not supporting them at the moment:

<CORSConfiguration> 
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

In the meanwhile you can build out your own server that proxies the images with a correct CORS header as explained here:

var http = require('http');
var request = require('request');
http.createServer(function(req, res) {
  if (req.url.match(/path=(.*)/))) {
    res.setHeader('access-control-allow-origin'), '*');
    request.get(req.url.match(/path=(.*)/)[1].pipe(res);
  } else {
  res.statusCode = 404;
  res.end();
  }
}).listen(8000);

This will allow you to use JSZip on the client side (and you can host it for free on Heroku).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM