Blazor WebAssembly组件中通过JS Interop调用window.onload及Moneris支付集成问题
Blazor WebAssembly组件中通过JS Interop调用window.onload及Moneris支付集成问题
嘿,我来帮你排查这个问题!你当前的代码逻辑里藏着一个关键的时机冲突,导致Moneris的消息监听没按预期生效,咱们一步步拆解清楚:
问题根源
Blazor WebAssembly的OnAfterRenderAsync在firstRender触发时,整个页面的window.onload其实早就执行完毕了——浏览器会在所有页面资源加载完成后立刻触发window.onload,而Blazor组件的渲染是在页面加载完成之后才启动的。这时候你再给window.onload赋值新函数,这个函数根本不会被触发,自然也就没法注册message事件监听了。
解决方案
我们完全不需要依赖window.onload,直接在Blazor组件渲染完成(也就是firstRender时机)直接注册message事件监听即可——因为这时候目标iframe已经存在于DOM中了。另外,你的JS代码里用eval解析消息数据存在安全风险,建议换成更安全的JSON.parse来处理。
修改后的Blazor组件代码
这部分改动很小,依然保持在firstRender时调用JS方法:
protected override async Task OnAfterRenderAsync(bool firstRender) { Console.WriteLine("hello test"); if (firstRender) { Console.WriteLine("invoking this function"); await JSRuntime.InvokeVoidAsync("MonerisEvents.registerMessageListener"); } }
修改后的JavaScript代码(wwwroot目录下)
我们把原来的setWindowOnLoad改成直接注册事件的方法,同时替换eval为安全的JSON.parse:
window.MonerisEvents = { doMonerisSubmit: function doMonerisSubmit() { var monFrameRef = document.getElementById('monerisFrame').contentWindow; monFrameRef.postMessage('tokenize', 'https://esqa.moneris.com/HPPtoken/index.php'); // 正式环境记得替换为对应生产地址 return false; }, respMsg : function (e) { // 用JSON.parse替代不安全的eval var respData = JSON.parse(e.data); console.log(respData); console.log(respData.responseCode); console.log(respData.errorMessage); console.log(respData.bin); console.log(respData.dataKey); document.getElementById("monerisResponse").innerHTML = `${e.origin} SENT - ${respData.responseCode}-${respData.dataKey}-${respData.errorMessage}`; document.getElementById("monerisFrame").style.display = 'none'; }, registerMessageListener : function() { // 直接注册message事件,无需等待window.onload if (window.addEventListener) { window.addEventListener("message", this.respMsg, false); } else { // 兼容旧版IE(如果业务需要的话) if (window.attachEvent) { window.attachEvent("onmessage", this.respMsg); } } console.log("Moneris消息监听已成功注册"); } }
额外注意事项
- 确保iframe已渲染:调用
registerMessageListener时,Blazor组件里的<iframe id="monerisFrame">必须已经渲染到DOM中,否则会找不到元素。 - 匹配postMessage目标源:
doMonerisSubmit里指定的目标源https://esqa.moneris.com/HPPtoken/index.php要和Moneris的实际环境匹配,正式上线时要切换为生产环境地址。 - 清理事件监听:如果你的组件会被销毁重建,记得在组件销毁时调用JS方法移除
message事件监听(用window.removeEventListener),避免内存泄漏。
调整后应该就能正常监听到Moneris iframe返回的消息了,你可以试试看!
备注:内容来源于stack exchange,提问作者Fajitas Shawarma
相关产品推荐
相关产品推荐

