不触发CORS问题的window.open外链跳转替代方案
问题背景
页面原有一组外链,初始通过target="_blank"设置为新标签页打开。为支持用户自主选择跳转方式,新增了一个复选框切换布尔变量newwin的状态,当前通过如下函数实现跳转逻辑:
function dolink(myurl) { if (newwin) { window.open(myurl, '_blank').focus(); } else { window.open(myurl, '_self'); } }
函数基础功能正常,但触发了两类跨域相关异常:
- 新窗口打开时,控制台输出
Storage access automatically granted for origin “NEWSITE” on “MYSITE”提示 - 当前窗口打开时,目标站点存在资源被CORS规则拦截的问题
需求是实现和普通链接完全一致的无关联跳转,不需要和外链站点建立任何跨域关联。
最优实现方案
问题根源是window.open默认会保留新旧页面的上下文关联(opener引用、来源信息传递),会触发浏览器跨域权限校验逻辑,才会出现你遇到的异常。完全不需要用JS方法模拟跳转,直接复用原生<a>标签的默认跳转行为即可,彻底规避这类问题。
方案1:改造现有跳转函数
动态生成临时a标签触发原生跳转,新窗口打开时加上rel="noopener noreferrer"切断所有跨域关联,和用户手动点击原生链接的效果完全一致:
function dolink(myurl) { const tempLink = document.createElement('a'); tempLink.href = myurl; tempLink.target = newwin ? '_blank' : '_self'; // 新窗口场景下彻底切断页面间关联,避免跨域校验 if (newwin) { tempLink.rel = 'noopener noreferrer'; } // 触发原生点击跳转 document.body.appendChild(tempLink); tempLink.click(); document.body.removeChild(tempLink); // 新窗口场景下需要聚焦的话,正常点击默认就会聚焦,不需要额外调用focus方法 }
说明:
noopener属性会阻止新页面获取当前页面的window.opener引用,noreferrer会阻止跳转时携带当前页面的来源信息,两个属性配合即可完全消除跨域关联,不会再触发存储授权提示、CORS拦截问题。
方案2:直接批量修改链接属性(更推荐)
不需要给每个链接绑定点击事件调用跳转函数,直接在复选框状态切换时,批量修改页面所有外链的target和rel属性即可,性能更好也更符合原生交互逻辑:
// 替换成你页面上的复选框、外链对应选择器 const winToggle = document.querySelector('#newwin-toggle'); const externalLinks = document.querySelectorAll('a[href^="http"]'); // 初始化默认状态 updateLinkTarget(); // 复选框切换时更新所有链接属性 winToggle.addEventListener('change', updateLinkTarget); function updateLinkTarget() { const openInNewWin = winToggle.checked; externalLinks.forEach(link => { link.target = openInNewWin ? '_blank' : '_self'; link.rel = openInNewWin ? 'noopener noreferrer' : ''; }); }
这种方案完全走浏览器原生链接跳转逻辑,没有额外的JS上下文干扰,不会出现你目前遇到的所有跨域相关异常。
内容的提问来源于stack exchange,提问作者Maelstrom
相关产品推荐
相关产品推荐

