2013-01-04 21 views
9

tôi là tạo ra một iframe lập trình bằng cách sử dụng "dữ liệu" URI:lập trình truy cập vào một iframe có sử dụng một dữ liệu URI như một nguồn

<iframe id="myFrame" src='data:text/html;charset=utf-8,<!DOCTYPE html><html><head></head><body><h1>Hello.</h1></body></html>'></iframe>​ 

khung này tải tốt, nhưng có vẻ như làm việc với các iframe lập trình truy cập kiểm tra bảo mật tên miền chéo.

var iframeDoc = document.getElementById('myFrame').contentWindow.document; 
$(iframeDoc.body).find('h1').text('Changed'); 

Ném một lỗi trong Chrome và Safari:

Unsafe JavaScript attempt to access frame with URL data:text/html;charset=utf-8,... from frame with URL http://... The frame requesting access has a protocol of 'http', the frame being accessed has a protocol of ''. Protocols must match.

Dưới đây là một fiddle hiển thị các lỗi an ninh: http://jsfiddle.net/bhGcw/4/

Firefox và Opera không ném ngoại lệ này và cho phép các nội dung iframe được đã thay đổi. Có vẻ như Webkit thấy giao thức trống cho URI dữ liệu và coi đây là vi phạm tên miền chéo.

Có cách nào xung quanh vấn đề này không?

+1

phải không? http://code.google.com/p/chromium/issues/detail?id=82402 nó dành cho crom chứ không phải chrome, nhưng có thể nó có cùng vấn đề. tôi cũng tìm thấy một số vấn đề bảo mật cho lừa đảo, mà chrome cố gắng ngăn chặn, nó có thể là nó quá – llamerr

+0

Vâng, chắc chắn có vẻ liên quan. Đã hy vọng rằng có một cách giải quyết, nhưng dường như không có. –

Trả lời

5

Dường như Webkit làm một so sánh chuỗi đơn giản trong domain checking code của họ:

String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow) 
{ 
    ... 

    SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin(); 
    SecurityOrigin* targetOrigin = document()->securityOrigin(); 
    if (targetOrigin->protocol() != activeOrigin->protocol()) 
     return message + " The frame requesting access has a protocol of '" + activeOrigin->protocol() + "', the frame being accessed has a protocol of '" + targetOrigin->protocol() + "'. Protocols must match.\n"; 

    ... 
} 

Dường như Chromium đang được nghiêm ngặt hơn spec HTML5, ít nhất là theo các báo cáo lỗi sau:

Chromium devs dường như không có lợi cho việc thư giãn quy tắc này. Rất tiếc.

+1

Nhận xét thú vị, nhưng tiếc là nó không trả lời câu hỏi – mems

7

Hơi trễ một chút, thay vì sử dụng URL dữ liệu, bạn sử dụng thuộc tính HTML5 srcdoc.

<iframe id="iframe" srcdoc='<html><body><h1>Hello!</h1></body></html>'></iframe> 
<script type="text/javascript"> 
    $(function(){ 
     $($("iframe")[0].contentWindow.document).find("h1").text("Modified from the parent window!"); 
    }); 
</script> 

Có một ví dụ tại http://jsfiddle.net/ff3bF/

+2

srcdoc không hoạt động trên IE/Edge. – Seanonymous

+1

Đó là một chút thất vọng.Một người nào đó đã viết một polyfill (https://github.com/jugglinmike/srcdoc-polyfill) – Jamie

3

Câu trả lời được đưa ra bởi @jamie hoạt động tốt cho bốc HTML vào iframe và cho phép tương tác programatic tiếp theo với các tài liệu nội dung.

XHTML không dễ dàng như vậy.

Thuộc tính srcdoc dường như bị giới hạn ở HTML, không phải XHTML.

Công việc xung quanh là sử dụng URL Blob cho phép chỉ định content-type.

var documentSource = '<?xml version="1.0" encoding="UTF-8"?>\n<html xmlns="http://www.w3.org/1999/xhtml">\n<head>...'; 
var blob = new Blob([documentSource], { type: "application/xhtml+xml" }); 
iframe.src = URL.createObjectURL(blob); 

Kỹ thuật này hoạt động cho ít nhất Chrome, Firefox và Safari.