打开第三方授权弹窗获取URL中code时触发跨域错误如何解决
报错原因
该报错是浏览器同源策略的强制安全限制导致的:当你打开的授权弹窗跳转到第三方域名后,该窗口的源与你的站点http://localhost:3000不属于同源,浏览器会禁止父页面读取跨源窗口的所有属性,你代码中访问windowReference.location.href的操作刚好触发了这个限制,因此抛出DOMException。
解决方案
按标准OAuth2.0授权码流的实现逻辑调整即可,全程不会触发跨源限制:
- 先在你使用的授权平台后台,将授权回调地址配置为你的站点同域地址,例如
http://localhost:3000/oauth-callback - 在你的站点新增
/oauth-callback路由对应的页面,该页面仅负责提取URL中的code参数,将code回传给父窗口后自动关闭 - 修改原父窗口代码,移除直接读取弹窗location的逻辑,新增监听回调页面回传消息的逻辑
父窗口调整后代码
var windowReference; // 监听回调页面发来的授权code window.addEventListener('message', (e) => { // 安全校验:只接受来自本站点的消息 if (e.origin !== 'http://localhost:3000') return; const authCode = e.data.code; if (authCode) { // 此处调用你自己的API发送code即可 console.log('获取到授权code:', authCode); } }) const openAccessWindow = async () => { if (windowReference == null || windowReference.closed) { windowReference = window.open( 'https://sandbox-api.some_more_information', 'Records', 'popup' ); } else { windowReference.focus() } }
/oauth-callback 页面代码
window.onload = function() { // 从URL参数中提取code const urlParams = new URLSearchParams(window.location.search); const authCode = urlParams.get('code'); if (authCode) { // 把code回传给父窗口 window.opener.postMessage({ code: authCode }, 'http://localhost:3000'); } // 处理完成后自动关闭弹窗 window.close(); }
注意事项
- 上线部署时请将代码中的
http://localhost:3000替换为你的实际站点域名 - 生产环境建议对postMessage传递的内容增加签名校验,进一步降低安全风险
内容的提问来源于stack exchange,提问作者Hilary
相关产品推荐
相关产品推荐

