场景
最新在做一个H5功能,做附件下载。
适用场景: 新窗口打开一个连接。
思路
根据附件id查询出附件地址之后,利用 window.open(failUrl)
打开新窗口来下载附件。
现象
安卓手机所测试的常用浏览器基本上都没问题,唯独iphone手机自带的safari浏览器不生效。
解决办法
对safari浏览器做特殊判断。
- 判断safari浏览器的方法
/* 判断是否是ios手机safari浏览器打开的 */
export const isIosSafari = () => {
const ua = navigator.userAgent.toLowerCase();
if (
ua.indexOf('applewebkit') > -1 &&
ua.indexOf('mobile') > -1 &&
ua.indexOf('safari') > -1 &&
!(ua.indexOf('android') > -1) &&
!(ua.indexOf('linux') > -1) &&
!(ua.indexOf('crios') > -1) &&
!(ua.indexOf('chrome') > -1) &&
!(ua.indexOf('browser') > -1) &&
!(ua.indexOf('ios') > -1)
) {
return true;
}
return false;
};
方案一 (推荐)
先打开一个空白窗口,然后再给窗口赋值地址。
// 按钮
this.handleDownload(item)}>下载文件
/* 下载文件方法 */
handleDownload = (item) => {
const { dispatch } = this.props;
// 要先定义打开新窗口,否则也会被拦截 不生效
const winRef = window.open("about:blank","_blank");
dispatch({
type: 'common/downloadFile',
payload: { fileId: item.fileId },
callback: (data) => {
// 后台接口返回回来的地址 fileUrl1
const fileUrl1 = data.fileUrl;
winRef.location = fileUrl1;
}
});
};
如果const winRef = window.open("about:blank","_blank");
放在异步回调函数中,恭喜你,不会生效,会被拦截哟~
方案二
当时safari浏览器的时候,我们通过超链接点击来跳转。
创建的标签,执行TagA.click()方法,在safari上也是不生效的,有老铁说safari下的A标签默认是没有绑定事件,那么我们就可以手动绑定一个事件,然后触发即可。
/* 利用a标签下载附件 */
downloadFileByTagA = (fileUrl) => {
const TagA = document.createElement('a');
TagA.href = fileUrl;
// TagA.target = '__blank';
document.body.appendChild(aSpan);
TagA.className = 'oInput';
TagA.style.display = 'none';
// 兼容ios safari浏览器
const e = document.createEvent('MouseEvent');
e.initEvent('click', false, false);
TagA.dispatchEvent(e);
}
上诉代码我注释掉了TagA.target = '__blank';
应为我加上去之后就不生效了,被safari安全机制拦截了。
当然这个可以通过 苹果系统设置,偏好设置->安全性,去掉阻止弹窗的复选框 来解决~~~。
方案三
生成一个a标签,让用户自己去点击。这个无论如何都不会被拦截。
不过这样也不好,会使用户多一步操作。
方案四
苹果系统设置,偏好设置->安全性,去掉阻止弹窗的复选框,如上所述。不太推荐,改变了用户的主观意愿
复盘分析
首先连接是无论如何不会被拦截的,可以生成一个连接让用户去点击,这样不太友好~~~
我是一个连接呀
为什么会被拦击呢?
当然是window.open
被广告商滥用,严重影响用户的使用。
当然也不是所有的window.open
都会被拦截,我们只需要找准时机去触发即可。
避免在回调函数中去执行window.open
方法。