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>我们正在处理用户关于PostgreSQL中“unresolvedgroupingkeyinWindowquery”错误的解决方案的问题。根据错误信息,这通常发生在窗口函数中引用的列不在GROUPBY子句或聚合函数中,导致分组键未解析。我们将按照以下步骤提供解决方案:1.理解错误原因2.提供修改查询的方法3.举例说明4.注意事项注意:用户要求使用中文回答,并且按照指定的格式要求(如数学表达式格式、引用标识等)。同时,我们需要生成相关问题。由于用户提供的引用[1]是关于HAProxy的stick-table配置,与当前问题无关,因此我们将忽略该引用。我们将基于PostgreSQL的窗口函数和分组查询的知识来解答。步骤:1.错误原因:在包含窗口函数的查询中,如果查询中同时使用了GROUPBY子句,那么窗口函数中引用的列必须要么在GROUPBY子句中,要么在聚合函数内。否则,PostgreSQL无法确定如何为每个分组计算窗口函数,因此报错。2.解决方案:-确保窗口函数中引用的所有列都在GROUPBY子句中列出。-或者,将窗口函数中引用的列放入一个聚合函数中(如MAX,MIN,AVG等),但这会改变原意,通常不适用于窗口函数。-另一种方法是,如果不需要分组,则移除GROUPBY子句;如果需要分组,考虑使用子查询或公共表表达式(CTE)先进行分组聚合,然后再对聚合结果使用窗口函数。3.示例:错误查询示例:```sqlSELECTdepartment,salary,AVG(salary)OVER(PARTITIONBYdepartment)FROMemployeesGROUPBYdepartment;```这里,`salary`列既不在GROUPBY子句中,也不在聚合函数内,但出现在窗口函数中(AVG(salary)实际上是在窗口函数内,但注意窗口函数是在GROUPBY之后执行的,所以这里salary列在分组后不可用)。正确的做法是:方法1:将salary加入GROUPBY```sqlSELECTdepartment,salary,AVG(salary)OVER(PARTITIONBYdepartment)FROMemployeesGROUPBYdepartment,salary;```但是这样会按部门和薪水分组,可能不是我们想要的(因为每个薪水一行,窗口函数按部门分区,计算每个部门的平均薪水,但这样每个部门会有多行相同的平均薪水值)。方法2:先聚合再使用窗口函数(如果目的是得到每个部门的平均薪水,然后还要展示每个部门的其他聚合信息):```sqlSELECTdepartment,AVG(salary)OVER(PARTITIONBYdepartment)ASavg_salaryFROMemployeesGROUPBYdepartment;```这里,我们只选择了department,并在窗口函数中计算了平均薪水(注意:这里AVG(salary)实际上是在分组后对每个部门计算平均值,因为GROUPBY已经将数据按部门分组,然后窗口函数再按部门分区,由于每个分组只有一个部门,所以窗口函数计算的就是该部门的平均薪水。但是,这个查询中窗口函数是多余的,因为直接使用AVG(salary)然后GROUPBYdepartment即可。所以这个例子可能并不典型。)更典型的例子是,我们想先进行分组聚合,然后对聚合后的结果进行窗口操作。例如,我们想得到每个部门的平均薪水,然后计算每个部门平均薪水在整个公司中的排名。这时,我们可以使用子查询:```sqlSELECTdepartment,avg_salary,RANK()OVER(ORDERBYavg_salaryDESC)FROM(SELECTdepartment,AVG(salary)ASavg_salaryFROMemployeesGROUPBYdepartment)ASdept_avg;```4.注意事项:-在编写包含窗口函数和GROUPBY的查询时,要清楚查询的执行顺序:先WHERE、GROUPBY、HAVING,然后才是窗口函数的执行。-在GROUPBY之后,只有分组列和聚合函数的结果是可用的,非分组列必须通过聚合函数才能使用。-如果窗口函数中引用了非分组列,且该列没有使用聚合函数,那么就会出现这个错误。生成相关问题:1.如何正确地在PostgreSQL中使用窗口函数和GROUPBY子句?2.窗口函数在SQL查询中的执行顺序是怎样的?3.除了窗口函数,PostgreSQL中还有哪些方法可以进行分组内的计算?根据以上分析,我们给出回答。</think>### PostgreSQL "unresolved grouping key in Window query" 错误解决方案 #### 错误原因分析 该错误发生在同时使用 **窗口函数** 和 **GROUP BY 子句** 的查询中。当窗口函数引用的列既未包含在 GROUP BY 子句中,也未通过聚合函数处理时,PostgreSQL 无法确定如何分组计算这些列,导致`unresolved grouping key`错误[^1]。 数学表达式示例: 设查询为 $$SELECT \text{column1}, \text{window\_function}(\text{column2}) \ OVER (...) \ FROM \ table \ GROUP BY \ \text{column1}$$ 若 column2 未在 GROUP BY 或聚合函数中,即违反分组规则 $\text{column2} \notin \mathcal{G}$($\mathcal{G}$ 为分组键集合),则触发错误。 --- #### 解决方案 ##### 方法 1:将缺失列加入 GROUP BY ```sql SELECT department, employee_name, AVG(salary) OVER (PARTITION BY department) FROM employees GROUP BY department, employee_name; -- 添加缺失的 employee_name ``` ##### 方法 2:使用聚合函数包裹列 ```sql SELECT department, MAX(employee_name) AS employee_name, -- 使用 MAX() 聚合 AVG(salary) OVER (PARTITION BY department) FROM employees GROUP BY department; ``` ##### 方法 3:子查询分层处理(推荐) ```sql SELECT department, employee_name, dept_avg_salary FROM ( SELECT department, AVG(salary) OVER (PARTITION BY department) AS dept_avg_salary FROM employees GROUP BY department -- 先聚合 ) AS agg JOIN employees USING (department); -- 再关联详细信息 ``` ##### 方法 4:改写为聚合函数 + 窗口分区 ```sql SELECT department, AVG(salary) OVER (PARTITION BY department) AS dept_avg, PERCENT_RANK() OVER (ORDER BY AVG(salary)) -- 对聚合结果应用窗口函数 FROM employees GROUP BY department; -- 确保所有非聚合列在 GROUP BY 中 ``` --- #### 关键原则 1. **分组一致性**:窗口函数中的列必须满足 $\forall c \in \text{Window\_Columns}, (c \in \mathcal{G}) \lor (\text{IsAggregate}(c))$ 2. **执行顺序**:GROUP BY 在窗口函数前执行,分组后非聚合列不可访问 3. **分区对齐**:窗口分区键应包含在 GROUP BY 子句中 > **注意**:在严格模式(如 `sql_mode=ONLY_FULL_GROUP_BY`)下此错误更常见,可通过 `SET sql_mode=''` 临时关闭(不推荐)[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值