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

解决下载功能

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

x-frame-options,是否允许 object 和 iframe 展示,有三个参数:

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

MDN的解释

我的后端同事在要下载的几个接口中,把 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 ,就会自动下载一个文件了

使用 window.open

如果我们是点击一个目标,然后同步执行打开窗口操作,用 window.open 是可以的,但是我们把 window.open 放在异步操作里就有问题了

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

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

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

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

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 这样就好了

js 打开新窗口方式的更多相关文章

  1. JS打开新窗口防止被浏览器阻止的方法

    这篇文章主要介绍了JS打开新窗口防止被浏览器阻止的方法,分析对比了常用方法与改进方法,是非常实用的技巧,需要的朋友可以参考下 本文实例讲述了JS打开新窗口防止被浏览器阻止的方法.分享给大家供大家参考. ...

  2. JS打开新窗口防止被浏览器阻止的方法[转]

    本文实例讲述了JS打开新窗口防止被浏览器阻止的方法.分享给大家供大家参考.具体分析如下: 用传统的window.open()方式打开新窗口,会被浏览器阻止,那么,我们如何才能让JS打开新窗口不被浏览器 ...

  3. Js打开新窗口拦截问题整理

    一.js打开新窗口,经常被拦截 //js打开新窗口,经常被拦截 //指定本窗口打开,可以使用 window.open('http://www.tianma3798.cn', '_self'); //不 ...

  4. js页面跳转 和 js打开新窗口 方法

    js页面跳转 和 js打开新窗口 方法 第一种: 第二种: 第三种: 第四种: 第五种: 1.在原来的窗体中直接跳转用 window.location.href="你所要跳转的页面" ...

  5. 浏览器拦截js打开新窗口

    最近做项目时,遇到的问题"想通过javascript在浏览器新标签页或新窗口打开一个新的页面,结果被浏览器大大无情给拦截了"业务需求:前端提交数据到后端,后端返回url,然后在新窗 ...

  6. js 打开新窗口

    以前老是用window.open方法打开浏览器新窗口,但是有的浏览器会阻止打开新窗口,一劳永逸的方式是通过js伪造a标签请求打开新窗口,代码如下: var atag = document.create ...

  7. js打开新窗口,js打开居中窗口,js打开自定义窗口

    ================================ ©Copyright 蕃薯耀 2020-01-07 https://www.cnblogs.com/fanshuyao/ var is ...

  8. 浏览器禁止js打开新窗口

    在项目中,有个需求是需要ajax获取新地址,然后去打开该页面地址,这样会被浏览器拦截,可以采取以下方式:1.再ajax请求先前,先创建一个新窗口 var newTab = window.open('' ...

  9. 用JS打开新窗口,防止被浏览器阻止的方法

    相信做web前端或者使用JS的朋友都会遇到需要在新窗口打开页面的情况,现在浏览器大都具有弹出窗口拦截功能,所以传统的window.open()不再那么好用了.借鉴于网上查到的方法和我个人的实践,把弹出 ...

随机推荐

  1. WdatePicker插件知识整理(一)

    当WdatePicker.js里的属性:$wdate=true时,在input里加上class="Wdate"就会在选择框右边出现日期图标,如果您不喜欢这个样式,可以把class= ...

  2. android物理动画、Kotlin客户端、架构组件、菜单效果、应用选择器等源码

    Android精选源码 Android一个有趣的Android动画交互设计 android可伸缩日历效果源码 关于界面,全新的卡片风格,支持夜晚模式 Android 用 Kotlin 实现的基于物理的 ...

  3. imx6q-plus-Android6.0下uboot添加网卡驱动

    1.文件:iTOP-iMX6_android6.0.1/bootable/bootloader/uboot-imx/include/configs/mx6sabre_common.h修改如下:#def ...

  4. SpringBoot 系列 - 自己写starter

    原文地址: https://www.xncoding.com/2017/07/22/spring/sb-starter.html 前言: Spring Boot由众多Starter组成,随着版本的推移 ...

  5. android版本更新框架、新闻客户端、音乐播放器、自定义View、Github客户端、指南针等源码

    Android精选源码 XUpdate 一个轻量级.高可用性的Android版本更新框架 Android一个可定制的圆形进度条 Android自定义View分享 打钩动画源码 android音乐文件播 ...

  6. JSON — Java与JSON数据互转

    转换时Bean所要求的: 被转换的Bean必需是public的. Bean被转换的属性一定要有对应的get方法,且一定要是public的. Bean中不能用引用自身的this的属性,否则运行时出现et ...

  7. Heartbeat(注意iptables和selinux的问题)

    安装 yum –y install heartbeat libnet配置 通过yum安装配置文件目录/etc/ha.d目录下没有配置文件需要从doc目录中复制三个文件.ha.cf.authkeys.h ...

  8. RDS的tar文件恢复到本地mysql5.7版本数据库

    参考博客: 安装qpress软件 https://blog.csdn.net/a18838964650/article/details/82800621 文章介绍补充 https://www.cnbl ...

  9. caffe之那些依赖的库

    1. Boost库 Boost是一个可移植的,提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一.Boost强调对跨平台的支持,编译与平台无关.Caffe采用C++为主要开发语言 ...

  10. 别恐慌,大众关心的人工智能问题学界都在努力求解——我眼中的AAAI 2015大会

    2015大会" title="别恐慌,大众关心的人工智能问题学界都在努力求解--我眼中的AAAI 2015大会"> 作者:微软亚洲研究院副研究员 黄铂钧 今年是美国 ...