窗里窥窗--window.open()的踩坑经历
2023-12-16 14:05:06
窗里窥窗--window.open()的踩坑经历
在日常工作中,难免会遇到一些小坑。今天,我就想和大家分享一个我在后台项目中遇到的坑,以及我如何解决的。
事情是这样的,我在项目中有一个按钮,点击这个按钮,需要发送一个请求,然后用请求到的data中的url打开一个新窗口(跳转到另一个后台)。看起来应该没什么问题,很快我就写好了代码(vue项目,以下是伪代码,主要表达下思路):
handleClick() {
axios.get('/api/get_url').then((res) => {
window.open(res.data.url);
});
}
愉快地测试下,发现并没有弹出新窗口,短促的慌乱之后,发现…
原来,这是因为浏览器的安全策略 在作祟。
安全策略:同源策略
浏览器为了保护用户的数据安全,会对跨域请求进行限制。这种限制就是同源策略 。
同源策略规定,只有来自同一个源(协议、域名、端口)的请求才能被浏览器允许。也就是说,如果一个请求的源与当前页面的源不一致,那么浏览器就会阻止这个请求。
在我们的例子中,点击按钮后发送的请求是跨域的,因为请求的源是/api/get_url
,而当前页面的源是localhost:8080
。因此,浏览器阻止了这个请求,也就没有打开新窗口。
解决方法
要解决这个问题,有两种方法:
- 使用CORS(Cross-Origin Resource Sharing)来允许跨域请求。
- 使用
window.open()
的target
属性来指定新窗口的来源。
方法一:使用CORS
CORS是一种允许跨域请求的机制。它通过在HTTP头部中添加一些额外的字段来告诉浏览器,该请求是允许跨域的。
要使用CORS,需要在服务器端设置CORS头部。在我们的例子中,可以使用以下代码在Node.js中设置CORS头部:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
设置好CORS头部后,就可以在客户端使用CORS发送跨域请求了。在我们的例子中,可以使用以下代码发送跨域请求:
axios.get('/api/get_url', {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
}
}).then((res) => {
window.open(res.data.url);
});
方法二:使用window.open()
的target
属性
window.open()
函数的target
属性可以指定新窗口的来源。如果将target
属性设置为_blank
,那么新窗口就会以空白页面的方式打开。
window.open(res.data.url, '_blank');
使用这种方法,就不需要设置CORS头部了。但是,需要注意的是,这种方法只适用于新窗口的内容与当前页面无关的情况。如果新窗口的内容与当前页面有关,那么就需要使用CORS来允许跨域请求。
总结
在本文中,我分享了自己在后台项目中使用
window.open()
时遇到的一个坑,以及解决方法。我也深入探讨了window.open()
的原理和安全策略,帮助读者更好地理解和使用这个函数。
希望这篇文章对大家有所帮助。如果您还有其他问题,欢迎在评论区留言。