问题原因:
Chrome的新版本删除了对 iframe跨域 origin中 alert()
、confirm()
和 prompt()
的支持。
相关文档:https://www.chromestatus.com/feature/5148698084376576
解决方法:
通过Window.postMessage()
从iframe发送消息到父页面,并通过父页面显示对话框。
实现代码:
https://example-a.com/parent.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Parent (domain A)</title> <script type="text/javascript" src="dialogs.js"></script> </head> <body> <h1>Parent (domain A)</h1> <iframe src="https://example-b.com/iframe.html"> </body> </html>
https://example-b.com/iframe.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Iframe (domain B)</title> <script type="text/javascript" src="dialogs.js"></script> </head> <body> <h1>Iframe (domain B)</h1> <script type="text/javascript"> alert('alert() forwarded from iframe.html'); confirm('confirm() forwarded from iframe.html via callback', (result) => { console.log('confirm() result via callback: ', result); }); prompt('prompt() forwarded from iframe.html via callback', null, (result) => { console.log('prompt() result via callback: ', result); }); (async () => { var result1 = await confirm('confirm() forwarded from iframe.html via promise'); console.log('confirm() result via promise: ', result1); var result2 = await prompt('prompt() forwarded from iframe.html via promise'); console.log('prompt() result via promise: ', result2); })(); </script> </body> </html>
dialogs.js
(function() { var id = 1, store = {}, isIframe = (window === window.parent || window.opener) ? false : true; // Send message var sendMessage = function(windowToSend, data) { windowToSend.postMessage(JSON.stringify(data), '*'); }; // Helper for overridden confirm() and prompt() var processInteractiveDialog = function(data, callback) { sendMessage(parent, data); if (callback) store[data.id] = callback; else return new Promise(resolve => { store[data.id] = resolve; }) }; // Override native dialog functions if (isIframe) { // alert() window.alert = function(message) { var data = { event : 'dialog', type : 'alert', message : message }; sendMessage(parent, data); }; // confirm() window.confirm = function(message, callback) { var data = { event : 'dialog', type : 'confirm', id : id++, message : message }; return processInteractiveDialog(data, callback); }; // prompt() window.prompt = function(message, value, callback) { var data = { event : 'dialog', type : 'prompt', id : id++, message : message, value : value || '' }; return processInteractiveDialog(data, callback); }; } // Listen to messages window.addEventListener('message', function(event) { try { var data = JSON.parse(event.data); } catch (error) { return; } if (!data || typeof data != 'object') return; if (data.event != 'dialog' || !data.type) return; // Initial message from iframe to parent if (!isIframe) { // alert() if (data.type == 'alert') alert(data.message) // confirm() else if (data.type == 'confirm') { var data = { event : 'dialog', type : 'confirm', id : data.id, result : confirm(data.message) }; sendMessage(event.source, data); } // prompt() else if (data.type == 'prompt') { var data = { event : 'dialog', type : 'prompt', id : data.id, result : prompt(data.message, data.value) }; sendMessage(event.source, data); } } // Response message from parent to iframe else { // confirm() if (data.type == 'confirm') { store[data.id](data.result); delete store[data.id]; } // prompt() else if (data.type == 'prompt') { store[data.id](data.result); delete store[data.id]; } } }, false); })();
或者可以将chrome降到92版本以下,可以使用--disable -features="SuppressDifferentOriginSubframeJSDialogs"
特性。
使用方法:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable -features="SuppressDifferentOriginSubframeJSDialogs"
或者
添加谷歌浏览器的快捷方式中,如下图: