HTML5 Canvas getImageData and Same Origin Policy

删除回忆录丶 提交于 2019-11-27 01:45:44

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

To configure your bucket to allow cross-origin requests, you create a CORS configuration, an XML document with rules that identify the origins that you will allow to access your bucket, the operations (HTTP methods) will support for each origin, and other operation-specific information. You can add up to 100 rules to the configuration. You add the XML document as the cors subresource to the bucket.

One possible solution is to use nginx to act as a proxy. Here is how to configure urls going to http://pixie.strd6.com/s3/ to pass on through to S3, but the browser can still believe that it is non-cross domain.

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

If you are using PHP, you can do something like:

    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;
    }

And access the image by using that php file, like if the file is called generateImage.php you can do <img src="http://GENERATEPHPLOCATION/generateImage.php"/> and the external image url can be a get parameter for the file

Recently, I came across $.getImageData, by Max Novakovic. The page includes a couple of neat demos of fetching and operating on Flickr photos, along with some code examples.

It allows you to fetch an image in JavaScript-manipulable form from an arbitrary site. It works by appending a script to the page. The script then requests the image from a Google App Engine server. The server fetches the requested image and relays it converted to base64 to the script. When the script receives the base64, it passes the data to a callback, which can then draw it onto a canvas and begin messing with it.

In the past Amazon S3 didn't allow you to modify or add the access-control-allow-origin and access-control-allow-credentials HTTP headers so it may have been better to switch to a different service like Rackspace Cloud Files or some other service that does.

Add or modify the HTTP headers like this:

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

See http://www.w3.org/TR/cors/#use-cases for more information.

Using a service that allows you to modify the HTTP headers entirely solves the same origin problem.

For people who do not use S3 can try to build a image proxy that encode the image file and wrap it into a JSON object.

Then you can use JSONP which supports cross domain to fetch the JSON object and assign the image data to img.src .

I wrote a sample code of the image proxy server with Google App Engine. https://github.com/flyakite/gae-image-proxy

The JSON object returns in the format like this

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

The 'data' is the image data in base64 format. Assign it to a image.

img.src = result.data;

The image is now "clean" for your canvas.

To edit your S3 bucket permissions:

1) Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/

2) In the Buckets list, open the bucket whose properties you want to view and click "add CORS configuration"

3) Write the rules you are willing to add in between the tags <CORSConfiguration>

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

You can learn more about rules at: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

4) Specify crossorigin='anonymous' on the image you'll use in your canvas

This behavior is by-design. Per the HTML5 spec, as soon as you draw a cross-origin image to a canvas, it is dirty and you can no longer read the pixels. Origin-matching compares the scheme, fully-qualified host, and in non-IE browsers, the port.

Just bumped into the same problem. I found out about CORS that might be helpful.

http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#14

It didn't work for me since I'm trying to manipulate an image from Flickr. So, I'm still looking for the solution.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!