window.open()在IE8下报错,输出文件无法下载,以及打开多个窗口重复的问题

本文详细描述了在IE8环境下使用JavaScript批量输出doc文件时遇到的问题及解决方案,包括IE缓存BUG、window.open多窗口打开问题以及安全性配置问题。最终通过配置IE安全性等级、修改window.open参数和解决代码兼容性问题成功实现了目标。

在业务里用到了PHP header导出doc文档,GET传值到页面,读出相应数据输出doc文件下载。用户提出需要批量,于是设计成js循环出对应数量的window.open(),向页面传入不同的值,批量输出相应的文件。简单的说,就是我需要循环出多个window.open()。

js代码为:

var outCode = JSON.parse(<?php echo $jsonCode; ?>);
for(var i=0; i<outCode.length; i++){
$statu = $("开始导出"+outCode[i]+"号申请表..").appendTo("body");
window.open("../docout.php?id="+outCode[i]);
$statu.append("已弹出下载,请注意");
}


(PHP页面省略)

实际过程中,在IE8上却出现了若干问题。花费不少时间。下面列举每个遇到的问题(均为IE8下,其他环境均不存在问题。吐)。

1、首先是单个的需要打开的是利用PHP header输出doc的页面,发现在使用<a href="url.php?id=code">链接形式传递时,新窗口正常打开并输出文件提示下载,没有问题。而改用window.open()打开却只有空白页面。

上网查找了一下解决方法:把IE个性化设置重置为默认(工具-Internet选项-高级-重置),删除所有个性化设置,完成后,重试IE该问题不再出现,窗口能正常打开。但是还有另外的问题:弹出窗后下载报错,下载框弹出提示"无法打开该站点,请求的站点不可用"...

p20130724091644

查找解决方法后发现是IE8的缓存BUG,需要加补丁。或在PHP输出中更改缓存模式。

加入header语句后问题解决。

header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

2、多个window.open弹出的问题单个的解决了,在批量循环弹出多个窗口打开页面时,IE8出现了这样的现象:循环开始,从打开第一个窗以后(默认在选项卡里打开),每次打开均把前一次的窗关闭又打开,一直重复,都只能出一个窗,也无法输出内容。怀疑是多个window.open只能出在一个窗上。

查阅资料,window.open的参数包括(url,name,feature,replace):

url:窗口链接,声明要在新窗口中显示的文档的 URLname:新窗口的名称。如果指定了一个已经存在的窗口,就不再创建一个新窗口,而只是返回对指定窗口的引用。feature:样式定制,例如高宽、滚动条等replace:url条目在历史记录里的生成方式,true替换浏览历史中的当前条目,false在浏览历史中创建新的条目

于是把每个窗口name赋予不同的名称,并将replace赋值为false,问题依然未能解决。

上了stack overflow,找到了一些相关问题,有所发现:首先提到name属性的标准解释,除了赋为自定义String,还有_blank _parent _self _top 。详细如下:

20130723-1

查看: msdn关于window.open()的解释

于是将name改为"_blank"。

window.open("../docout.php?id="+outCode[i],"_blank","",false);

问题解决,每个window.open都在新的窗口打开了。但是烦人的问题没有结束。。


3、这回真是折磨透了。。上传到服务器后仍然出现之前的问题。怎么改属性都也不起作用。折磨了一天,找到了问题所在:

(尝试过程省略一万字)

在本地时,IE8中本地站点安全性配置为中低,而internet默认级别为中高。于是尝试将站点加入可信站点内,并配置同样的中低安全性。问题解决了。。。估计是安全性配置中的防弹窗的问题。

配置方法:internet选项——安全——可信站点——添加,并将安全性设为中低

p20130724092918

在自定义级别中应该也能找到相应的选项,应该是禁用防弹窗,没试了。

到此,这个问题发现已经无法用代码去绕开了。只能记住下次不再用这方法实现任何功能。存在差异性。(其实都是IE...)


4、另外关于name在IE8的问题——拒绝空格和中划线
解答中其次提到,在name中,IE8不支持Space(空格)、dash(中划线-),如果在name中使用形如"my-window"或"my window",将会报错 Invalid argument。
吐槽:IE为什么不去见鬼。

参看stack overflow上相关问题:

ie8 var w= window.open() - “Message: Invalid argument.

Window.open not working in IE8?

本文也发表在我的独立博客blog.mc-zone.me上,点击 访问此文

<think>首先,用户的问题是关于使用 `window.open` 下载多个文件时导致浏览器打开报错页面的原因及解决方法。我需要基于提供的引用内容来回答。 回顾引用内容: - 引用[1]:提到 `window.open` 的异步加载问题,建议在 `onload` 事件中访问新窗口。 - 引用[2]:解决 Vue 中使用 `window.open` 的问题,使用 `window.location.replace('about:blank', '_self', '').close()` 来关闭空白页。 - 引用[3]:处理 `window.open` 打开 txt 文件乱码问题,由于浏览器直接打开文件。 - 引用[4]:Vue 中封装下载函数,使用 `Blob` 和 `URL.createObjectURL` 来下载文件。 - 引用[5]:使用 iframe 方式循环下载多个文件,避免弹出多个窗口。 用户的具体问题是:使用 `window.open` 下载多个文件时,浏览器打开报错页面的原因及解决方法。 可能的原因: 1. **弹出窗口被阻止**:浏览器可能阻止多个弹出窗口,导致一些窗口无法打开报错。 2. **异步加载问题**:`window.open` 是异步的,如果立即访问新窗口,可能导致错误(如引用[1]所述)。 3. **文件类型问题**:某些文件类型(如文本文件)可能被浏览器直接打开,而不是下载,导致乱码或错误(如引用[3]所述)。 4. **性能问题**:同时打开多个窗口可能导致浏览器资源耗尽,出现报错页面。 5. **安全限制**:浏览器有安全策略限制同时打开多个窗口。 解决方法: - 使用 iframe 方式下载文件(如引用[5]所示),避免弹出多个窗口。 - 使用 Blob 和创建链接的方式下载文件(如引用[4]所示),这更现代且避免弹出窗口。 - 确保文件下载链接正确,设置响应头以强制下载而不是打开。 - 处理窗口关闭问题,避免空白页残留(如引用[2]所示)。 回答结构: 1. **解释原因**:清晰列出导致报错页面的可能原因。 2. **提供解决方法**:给出具体的代码示例和步骤。 3. **引用相关引用**:在回答中自然地添加引用标识。 4. **生成相关问题**:在最后添加相关问题部分。 确保格式: - 行内数学表达式使用 `$...$`。 - 独立公式使用 `$$...$$`。 - 使用中文回答。 - 代码块用 \`\`\` 包裹。 最终回答结构: - 引言:简述问题。 - 原因分析。 - 解决方法。 - 代码示例。 - 总结。 - 相关问题。 生成相关问题: - 基于主题,如优化下载、处理不同文件类型、避免弹出窗口被阻止等。</think>### window.open 下载多个文件导致报错页面的原因及解决方法 在使用 `window.open` 下载多个文件时,浏览器可能打开报错页面或空白页,这通常是由以下原因引起的: 1. **浏览器安全策略限制**:现代浏览器(如 Chrome、Firefox)会阻止频繁弹出窗口,如果短时间内多次调用 `window.open`,部分窗口会被拦截或直接报错[^1][^2]。 2. **异步加载问题**:`window.open` 是异步操作,新窗口加载完成前访问其内容可能导致错误(如引用标识[^1]所述)。 3. **文件类型处理不当**:某些文件类型(如 TXT、PDF)可能被浏览器直接渲染而非下载,若编码不匹配(如 UTF-8 vs. GBK),会显示乱码或错误页面[^3]。 4. **资源竞争与内存泄漏**:同时打开多个窗口可能导致浏览器资源耗尽(如内存或连接数限制),触发崩溃或报错页面;未正确关闭窗口还会残留空白页[^2][^4]。 5. **跨域或响应头问题**:下载链接的响应头未设置 `Content-Disposition: attachment`,导致浏览器尝试渲染文件而非下载[^3][^4]。 #### 解决方法 以下提供两种可靠方案,优先推荐 **方法一**(避免弹出窗口),其次为 **方法二**(优化 `window.open`)。 **方法一:使用 iframe 或 Blob 下载(推荐)** 避免 `window.open` 弹出窗口,直接从后台获取文件流并下载。参考引用[^4][^5]的实现: ```javascript // 示例:循环下载多个文件(无弹出窗口) function downloadFiles(urlList) { urlList.forEach((url, index) => { const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = url; // 文件下载链接 document.body.appendChild(iframe); // 下载完成后移除 iframe,避免内存泄漏 setTimeout(() => document.body.removeChild(iframe), 1000); }); } // 或使用 Blob 方式(更现代,支持大文件) function downloadViaBlob(url, fileName) { fetch(url) .then(res => res.blob()) .then(blob => { const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = fileName; // 设置文件名 link.click(); URL.revokeObjectURL(link.href); // 释放资源 }); } ``` **优点**: - 无弹出窗口,完全规避浏览器拦截问题。 - 支持批量下载,通过循环处理多个文件[^5]。 - 避免空白页残留(自动清理 iframe 或 Blob 对象)[^2][^4]。 **方法二:优化 `window.open` 调用(需处理异步和关闭)** 若必须使用 `window.open`,需添加异步控制和窗口关闭逻辑: ```javascript // 示例:安全下载多个文件 function safeWindowOpenDownload(urlList) { urlList.forEach((url, i) => { setTimeout(() => { const newWindow = window.open(url, '_blank'); // 处理异步加载和关闭 newWindow.onload = function() { // 检查是否为错误页面(如 HTTP 404) if (newWindow.document.title.includes('Error')) { newWindow.close(); // 关闭报错页 } else { // 下载完成后关闭窗口(需服务器设置 Content-Disposition) setTimeout(() => { newWindow.close(); // 避免空白页:强制重定向并关闭 newWindow.location.replace('about:blank'); }, 1000); } }; }, i * 1000); // 间隔 1 秒,避免频率过高 }); } ``` **关键优化点**: - **添加延迟**:使用 `setTimeout` 间隔调用,减少同时触发风险[^1][^5]。 - **处理 onload 事件**:确保窗口加载完成后再操作,避免异步错误[^1]。 - **强制关闭空白页**:结合 `location.replace('about:blank')` 和 `close()` 彻底清理[^2]。 - **服务器端配置**:确保响应头包含 `Content-Disposition: attachment; filename="file.txt"`,强制下载而非打开[^3][^4]。 #### 总结 报错页面主要由浏览器安全策略、异步加载和资源泄漏引起。**优先采用 iframe 或 Blob 方案**(方法一),可彻底避免问题;若需兼容旧系统,使用方法二并严格处理窗口生命周期。实际部署时,还需确保服务器正确设置文件响应头[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值