如何在Google Chrome浏览器中调试跨(子)域postMessage通信的目标页面?
如何在Google Chrome浏览器中调试跨(子)域postMessage通信的目标页面?
我明白你现在遇到的问题——跨子域用postMessage通信时,没法给主域(iframe里的目标页面)加断点调试,确实挺头疼的。我来一步步教你怎么在Chrome里搞定这件事,顺便也说说你后面提到的配置问题:
一、两种快速调试跨域iframe目标页面的方法
方法1:单独打开目标页面,保持调试窗口监听
先直接在Chrome地址栏打开主域的目标页面(比如http://www.example.com/testxdommain.html),按F12打开DevTools:
- 切换到Sources面板,在左侧找到这个
testxdommain.html文件 - 在
window.addEventListener("message", function(e){...})的回调代码里加断点(点击代码行号即可) - 保持这个DevTools窗口不要关闭,回到子域的页面(
mysub.example.com的那个页面),点击按钮触发postMessage
这时候主域页面的DevTools就会命中断点,你可以正常调试变量、查看调用栈了。
方法2:直接在子域页面的DevTools里切换到iframe上下文
Chrome DevTools原生支持调试跨域iframe,不用单独打开页面:
- 打开子域页面的DevTools(按F12或右键选择「检查」)
- 切换到Sources面板,左侧找到Page > Frames,展开后就能看到主域iframe对应的文件(
testxdommain.html) - 打开这个文件,在目标代码行加断点,然后操作子域页面的按钮,就能直接命中断点调试了
二、关于你提到的CORS配置问题
你加的.htaccess和web.config里的CORS头其实和postMessage的跨域调试没关系哦!CORS是给AJAX/fetch这类请求用的,postMessage的跨域控制是靠你代码里的e.origin判断的,所以那些配置不影响postMessage的正常工作,也不影响调试,不用纠结这个。
附:你的代码整理(方便参考)
子域页面(mysub.example.com的文件)
<!DOCTYPE html> <html> <head> <title>Test Cross Domain Main - This is the html on the subdomain</title> </head> <body style="width:100%; height: 100%; padding: 0 0 0 0; margin: 0 0 0 0; overflow: hidden; background:#000000; font-family: 'Arial', sans-serif;"> <iframe style="display: none;" src="http://www.example.com/testxdommain.html" ></iframe> <button onclick="SaveNameToRoot()">Save Name To Local Storage Root</button> <button onclick="RemoveNameFromRoot()">Remove Name To Local Storage Root</button> <br /> <label id="name" style="color: white;">Label</label> <script type="text/javascript"> console.log("In testxdomsub.html"); function SaveNameToRoot(){ const iframe = document.querySelector("iframe"); const wind = iframe.contentWindow; const data = { isSet: true, slot: "name", data: "Wibble" } wind.postMessage(JSON.stringify(data), "*"); } function RemoveNameFromRoot(){ } // This is stuff coming back from the other window on main window.addEventListener("message", function(e){ const data = e.data; }); </script> </body> </html>
主域目标页面(www.example.com的文件)
<!DOCTYPE html> <html> <head> <title>Test Cross Domain Main - This is the html on the main site</title> </head> <body style="width:100%; height: 100%; padding: 0 0 0 0; margin: 0 0 0 0; overflow: hidden; background:#000000; font-family: 'Arial', sans-serif;"> <script type="text/javascript"> console.log("In testxdommain.html"); window.addEventListener("message", function(e){ console.log("e.origin: " /*+ e.origin*/); if(e.origin !== "mysite.com"){ return; } const data = JSON.parse(e.data); if(typeof data.slot !== "undefined"){ if(data.isSet){ if(typeof data.data !== "undefined"){ localStorage.setItem(data.slot, data.data); } }else{ } } }); </script> </body> </html>
最后提个小建议
调试的时候可以先在主域的message回调里加个console.log(data),确认能收到子域发的消息,再加断点,这样更容易排查问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

