js 打开新窗口方式

以前的项目,有个功能是下载文件,这里只要在浏览器输入 url 就会下载那个文件了。当时我只是简单得使用 window.open ,可是却会被浏览器进行拦截,要手动开启才行,而后就搜索研究其余方法,就看到各类各样的,经过 js 打开新窗口的方法了,这里就总结一下html

解决下载功能

这里就先说解决下载功能的方法,经过同事的提醒,改用 iframe 进行处理,直接对 iframe 的 src 进行赋值,就会自动进行下载文件了,不过,若是后端在 response header 设置了某个头部,就会报错了:x-frame-options: DENY前端

x-frame-options,是否容许 object 和 iframe 展现,有三个参数:后端

  • DENY: 即便是相同域名,也不能显示
  • SAMEORIGIN: 能够在相同域名页面展现
  • ALLOW-FROM uri: 任何来源均可以展现

MDN的解释api

个人后端同事在要下载的几个接口中,把 x-frame-options 设置成 SAMEOPIGIN 后,前端就能够在无任何反作用的状况下,经过 js 进行下载文件了浏览器

export: (url) => {
  // 移除旧的节点
  const oldNode = document.querySelector('#g-exportOrder-iframe')
  if (oldNode) {
    document.body.removeChild(document.querySelector('#g-exportOrder-iframe'))
  }
  // 生成新节点,进行下载
  const iframe = document.createElement('iframe')
  iframe.style.display = "none"
  iframe.id = 'g-exportOrder-iframe'
  iframe.src = url
  document.body.appendChild(iframe)
}

只要调用传个 url ,就会自动下载一个文件了app

使用 window.open

若是咱们是点击一个目标,而后同步执行打开窗口操做,用 window.open 是能够的,可是咱们把 window.open 放在异步操做里就有问题了异步

div.addEventListener('click', open, false)
function open() {
  setTimeout(() => {
    window.open('/api/admin/adslot/all')
  }, 1100)
}

我在谷歌、火狐和欧朋,这样就会被拦截,然而用 ie9 却不会被拦截,我给10秒,ie 最后仍是会弹出来url

从你用点击事件,到 window.open ,只要异步操做超过某个时间,浏览器就会拦截这个弹窗的操做code

若是不添加用户的事件去触发 window.open (好比点击事件,鼠标移入移出等),而是在代码直接运行 window.open 的话,那样浏览器也会拦截orm

window.onload = function() {
  windon.open()
}

总得来说,若是没有用用户操做的事件去触发 window.open 就会被拦截,而把 window.open 放在异步操做,且超过必定的事件,也会被拦截

这里先想到了解决异步也会被拦截的方法

var test = window.open()
setTimeout(function() {
  test.location = 'http://www.xxx.com'
}, 2000)

在异步操做前,先打开窗口,而后再在你要操做的位置,更改这个窗口的 location ,不过这个缺陷有点大,要等异步操做完成了,新的窗口才会从空白变到指定页面,并且这种解决不了,没有人为事件触发 window.open 致使被拦截的问题

使用 a 标签

这是最多见打开一个新标签页面的方法

<a class='test' href='http://www.xxx.com' target='_blank'></a>

而后,我点击另一个 div ,再打开新窗口

function open() {
  setTimeout(function() {
    document.querySelector('.test').click()
  }, 2000)
}

上面的异步操做,仍是不行,就算是从新生成一个 a 标签,再用 click() 触发也是不行

form submit

<form class='test' target='_blank' @click='open' method='GET' action='http://www.xxx.com'>click me</form>
function open2() {
  setTimeout(() => {
    document.querySelector('.test').submit()
  }, 2000)
}

和 a 标签同样

DEMO 连接

总结

若是要下载文件的话,使用 iframe

若是要打开新窗口,并且没有用户操做的前提下打开,是不能显示的,只能提示让用户关闭那个拦截吧

有用户操做,且是异步的状况下,就使用 window.open ,而后定义 location 这样就行了

相关文章
相关标签/搜索