2011-01-12 24 views
15

Tôi có một trang web đang chạy tại pixie.strd6.com và hình ảnh được lưu trữ thông qua Amazon S3 bằng CNAME cho images.pixie.strd6.com.HTML5 Canvas getImageData và Chính sách gốc tương tự

Tôi muốn để có thể rút ra những hình ảnh này đến một canvas HTML5 và gọi phương thức getImageData nhưng nó ném Error: SECURITY_ERR: DOM Exception 18

Tôi đã cố gắng thiết lập window.domain = "pixie.strd6.com", nhưng điều đó không có tác dụng.

Bên cạnh đó, $.get("http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982", function(data) {console.log(data)}) cũng ném một lỗi: XMLHttpRequest cannot load http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982 . Origin http://pixie.strd6.com is not allowed by Access-Control-Allow-Origin.

Lý tưởng nhất là HTML5 canvas sẽ không chặn gọi getImageData từ tên miền phụ. Tôi đã xem xét thiết lập một tiêu đề Access-Control-Allow-Origin trong S3, nhưng chưa thành công.

Bất kỳ trợ giúp hoặc cách giải quyết nào đều được đánh giá cao.

+34

chính sách cùng một nguồn gốc Đây là điều ngu xuẩn nhất bao giờ hết . Nếu tôi là một đoạn mã JavaScript độc hại và tôi muốn tải dữ liệu độc hại, tôi sẽ chỉ bao gồm thẻ tập lệnh tùy ý trong trang, không đọc "s3kri7 c0mm4nd5" từ dữ liệu hình ảnh. Những người duy nhất muốn đọc dữ liệu hình ảnh là khách hàng bên devs. Đối với việc ăn cắp "dữ liệu hình ảnh bí mật hàng đầu" từ một VPN, nếu trang web của bạn đã được xss'd thì keylogging sẽ tàn phá hơn nhiều. Tất cả điều này "bảo vệ" phục vụ để làm là làm nặng thêm các nhà phát triển hợp pháp cố gắng để có được JavaScript để làm đơn giản nhất của nhiệm vụ. –

+7

SOP đang bảo vệ chống lại một vectơ tấn công hợp pháp tại đây.Giả sử bạn có một album ảnh riêng trên trang web chia sẻ ảnh (hoặc kiểm tra hình ảnh được lưu trữ trong ngân hàng trực tuyến của bạn): không có bảo vệ vải bẩn, * bất kỳ trang nào trên Web * bạn truy cập sẽ có khả năng lấy những hình ảnh đó nếu họ biết URL và bạn đã đăng nhập vì các yêu cầu được gửi từ '' tags ** sử dụng cookie của bạn **. Vấn đề ở đây không phải là trang web XSS đã bị xâm nhập; vấn đề là * bất kỳ trang nào trên Web * đều có thể tìm nạp và đọc hình ảnh trên canvas bằng cookie xác thực của bạn. – apsillers

+2

** tl; dr: ** Hiện tại, bất kỳ trang web tên miền chéo nào cũng có thể hiển thị * hình ảnh yêu cầu của bạn (ảnh riêng tư, kiểm tra hình ảnh, v.v.) trong thẻ '', nhưng, nhờ SOP, họ không thể * đọc * nội dung của những hình ảnh đó trong canvas để, ví dụ, lưu chúng vào máy chủ. – apsillers

Trả lời

6

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.

1

Hành vi này là theo thiết kế. Theo thông số HTML5, ngay khi bạn vẽ hình ảnh có nguồn gốc chéo tới canvas, nó sẽ bị bẩn và bạn không thể đọc được pixel nữa. So khớp gốc so sánh lược đồ, máy chủ đủ điều kiện và trong các trình duyệt không phải của IE, cổng.

+0

Vì vậy, giải pháp thay thế có liên quan đến proxy thông qua máy chủ web của tôi không? –

+4

Có, mã máy chủ để proxy hình ảnh sẽ hoạt động, nhưng thật đáng buồn là chúng ta phải dựa vào thứ gì đó không cần thiết. Họ nên ít nhất là thực hiện các chính sách miền chéo thông qua một tập tin xml trên máy chủ mục tiêu, như đã được thực hiện với đèn flash. – Omiod

3

Một giải pháp có thể là sử dụng nginx để hoạt động như một proxy. Dưới đây là cách định cấu hình url sẽ truy cập http://pixie.strd6.com/s3/ để chuyển qua S3, nhưng trình duyệt vẫn có thể tin rằng đó là miền không phải là chéo.

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

Gần đây, tôi đã xem qua $.getImageData, bởi Max Novakovic. Trang này bao gồm một vài bản demo gọn gàng về tìm nạp và hoạt động trên ảnh Flickr, cùng với một số ví dụ về mã.

Tính năng này cho phép bạn tìm nạp hình ảnh ở dạng có thể điều chỉnh JavaScript từ một trang web tùy ý. Nó hoạt động bằng cách thêm một kịch bản vào trang. Tập lệnh sau đó yêu cầu hình ảnh từ máy chủ Google App Engine. Máy chủ tìm nạp hình ảnh được yêu cầu và chuyển nó thành chuyển đổi thành base64 thành tập lệnh. Khi kịch bản nhận base64, nó chuyển dữ liệu đến một cuộc gọi lại, sau đó có thể vẽ nó vào một khung vẽ và bắt đầu rối tung lên nó.

2

Trong quá khứ, Amazon S3 không cho phép bạn sửa đổi hoặc thêm các tiêu đề HTTP cho phép truy cập-kiểm soát-cho phép và truy cập-điều khiển-cho phép chứng thực để có thể chuyển sang một dịch vụ khác như Rackspace Cloud Files hoặc một số dịch vụ khác.

Thêm hoặc sửa đổi các tiêu đề HTTP như thế này:

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

Xem http://www.w3.org/TR/cors/#use-cases để biết thêm thông tin.

Sử dụng dịch vụ cho phép bạn sửa đổi tiêu đề HTTP hoàn toàn giải quyết cùng một vấn đề gốc.

3

Nếu bạn đang sử dụng PHP, bạn có thể làm một cái gì đó như:

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

Và truy cập hình ảnh bằng cách sử dụng tập tin php, như thế nào nếu các tập tin được gọi là generateImage.php bạn có thể làm <img src="http://GENERATEPHPLOCATION/generateImage.php"/> và hình ảnh bên ngoài url có thể là một tham số get cho các tập tin

2

Đối với những người không sử dụng S3 có thể cố gắng xây dựng một proxy hình ảnh mã hóa tệp hình ảnh và gói nó vào một đối tượng JSON.

Sau đó, bạn có thể sử dụng JSONP hỗ trợ tên miền chéo để tìm nạp đối tượng JSON và gán dữ liệu hình ảnh cho img.src.

Tôi đã viết mã mẫu của máy chủ proxy hình ảnh với Google App Engine. https://github.com/flyakite/gae-image-proxy

Lợi nhuận đối tượng JSON trong các định dạng như thế này

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

Các 'dữ liệu' là dữ liệu hình ảnh ở định dạng base64. Gán nó cho một hình ảnh.

img.src = result.data; 

Hình ảnh bây giờ "sạch" cho canvas của bạn.

2

Để chỉnh sửa quyền xô S3 của bạn:

1) Đăng nhập vào Management Console AWS và mở Amazon S3 console tại https://console.aws.amazon.com/s3/

2) Trong danh sách Xô, mở thùng mà các thuộc tính bạn muốn để xem và nhấp vào "thêm cấu hình CORS"

amazon-screen-shot

3) Viết các quy tắc bạn sẵn sàng để thêm vào giữa các thẻ <CORSConfiguration>

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

Bạn có thể tìm hiểu thêm về quy tắc tại địa chỉ: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

4) Xác định crossorigin = 'vô danh' trên hình ảnh mà bạn sẽ sử dụng trong canvas của bạn

Các vấn đề liên quan