mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
fix(react-dom): access iframe contentWindow instead of contentDocument (#15099)
MDN has a list of methods for obtaining the window reference of an iframe: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Syntax fix(react-dom): check if iframe belongs to the same origin Accessing the contentDocument of a HTMLIframeElement can cause the browser to throw, e.g. if it has a cross-origin src attribute. Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g: ```javascript try { $0.contentDocument.defaultView } catch (err) { console.log('err', err) } > Blocked a frame with origin X from accessing a frame with origin Y. Protocols, domains, and ports must match. > err – TypeError: null is not an object (evaluating '$0.contentDocument.defaultView') ``` A safety way is to access one of the cross origin properties: Window or Location Which might result in "SecurityError" DOM Exception and it is compatible to Safari. ```javascript try { $0.contentWindow.location.href } catch (err) { console.log('err', err) } > err – SecurityError: Blocked a frame with origin "http://localhost:3001" from accessing a cross-origin frame. Protocols, domains, and ports must match. ``` https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
This commit is contained in:
committed by
Dan Abramov
parent
e0c2c56dfd
commit
f00be84b81
+19
-5
@@ -40,15 +40,29 @@ function isInDocument(node) {
|
||||
);
|
||||
}
|
||||
|
||||
function isSameOriginFrame(iframe) {
|
||||
try {
|
||||
// Accessing the contentDocument of a HTMLIframeElement can cause the browser
|
||||
// to throw, e.g. if it has a cross-origin src attribute.
|
||||
// Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
|
||||
// iframe.contentDocument.defaultView;
|
||||
// A safety way is to access one of the cross origin properties: Window or Location
|
||||
// Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
|
||||
|
||||
return typeof iframe.contentWindow.location.href === 'string';
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getActiveElementDeep() {
|
||||
let win = window;
|
||||
let element = getActiveElement();
|
||||
while (element instanceof win.HTMLIFrameElement) {
|
||||
// Accessing the contentDocument of a HTMLIframeElement can cause the browser
|
||||
// to throw, e.g. if it has a cross-origin src attribute
|
||||
try {
|
||||
win = element.contentDocument.defaultView;
|
||||
} catch (e) {
|
||||
if (isSameOriginFrame(element)) {
|
||||
win = element.contentWindow;
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
element = getActiveElement(win.document);
|
||||
|
||||
Reference in New Issue
Block a user