返回

窗里窥窗--window.open()的踩坑经历

前端

窗里窥窗--window.open()的踩坑经历

在日常工作中,难免会遇到一些小坑。今天,我就想和大家分享一个我在后台项目中遇到的坑,以及我如何解决的。

事情是这样的,我在项目中有一个按钮,点击这个按钮,需要发送一个请求,然后用请求到的data中的url打开一个新窗口(跳转到另一个后台)。看起来应该没什么问题,很快我就写好了代码(vue项目,以下是伪代码,主要表达下思路):

handleClick() {
  axios.get('/api/get_url').then((res) => {
    window.open(res.data.url);
  });
}

愉快地测试下,发现并没有弹出新窗口,短促的慌乱之后,发现…

原来,这是因为浏览器的安全策略 在作祟。

安全策略:同源策略

浏览器为了保护用户的数据安全,会对跨域请求进行限制。这种限制就是同源策略

同源策略规定,只有来自同一个源(协议、域名、端口)的请求才能被浏览器允许。也就是说,如果一个请求的源与当前页面的源不一致,那么浏览器就会阻止这个请求。

在我们的例子中,点击按钮后发送的请求是跨域的,因为请求的源是/api/get_url,而当前页面的源是localhost:8080。因此,浏览器阻止了这个请求,也就没有打开新窗口。

解决方法

要解决这个问题,有两种方法:

  1. 使用CORS(Cross-Origin Resource Sharing)来允许跨域请求。
  2. 使用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()的原理和安全策略,帮助读者更好地理解和使用这个函数。

希望这篇文章对大家有所帮助。如果您还有其他问题,欢迎在评论区留言。