浏览器拦截打开新窗口情况总结

在打开一个新窗口时,由于浏览器的安全机制,用户未始终允许的情况下,可能会触发到浏览器拦截,无法正常直接弹出。网上有很多给出解决方案的只言片语,不够全面,所以针对自己遇到的问题做了详细的情况分析。总结成文,避免以后混淆。只分析使用 js 代码手动打开新窗口的方式。测试代码用例在此几种打开新窗口的方式window.open()创造 a 链接,手动触发 a.click()创造 form 表单,手动触发 form.submit() (创造 form 表单,添加 button 子元素,手动触发 button.click() 情况相同,不做区分)调用情形分组结果使用 Chrome(70)、Firefox(63)、Edge、IE(9-11) 作为测试浏览器,对以下列举的打开新窗口的情形做测试。x 表示被拦截,√ 表示新窗口正确打开直接打开即页面加载后直接调用打开新窗口代码方式ChromeFirefoxEdgeIEwindow.open()xxxxa.click()xxxxform.submit()xxxx用户点击行为按钮点击后直接打开即在按钮被点击的回调中,直接调用打开新窗口的代码方式ChromeFirefoxEdgeIEwindow.open()√√√√a.click()√√√√form.submit()√√√√按钮点击后延时打开即在按钮被点击的回调中,通过 setTimeout 执行打开新窗口代码方式ChromeFirefoxEdgeIEwindow.open()√√××a.click()√√××form.submit()√√××按钮点击后在异步请求回调中打开即在按钮被点击的回调中,发送请求,并在请求的回调中执行打开新窗口代码方式ChromeFirefoxEdgeIEwindow.open()xxxxa.click()xxxxform.submit()xxxx用户键盘行为我们以 input 元素进行测试(其他元素其他键盘事件也有相同效果),因为最可能使用的情况为 input 中使用回车打开新窗口。input keydown后直接打开方式ChromeFirefoxEdgeIEwindow.open()√x√xa.click()√x√xform.submit()√x√x其中 ie9、ie10虽然会弹出拦截弹窗提示,但是能打开新窗口按钮点击后延时打开方式ChromeFirefoxEdgeIEwindow.open()√xxxa.click()√xxxform.submit()√xxx按钮点击后在异步请求回调中打开方式ChromeFirefoxEdgeIEwindow.open()xxxxa.click()xxxxform.submit()xxxx规则总结就参与测试的浏览器,三种打开新窗口的方式对拦截结果没有影响。所有浏览器都不允许非用户操作引起的打开新窗口。所有浏览器都不允许在异步 ajax 请求中打开新窗口。Edge 和 IE 不允许在 setTimeout 中打开新窗口,Chrome、Firefox 允许在用户操作事件中的 setTimeout 中打开新窗口。Firefox 和 IE 不允许在用户键盘操作事件中打开新窗口解决方案需要在异步 ajax 请求中打开新窗口的可以使用请求前打开新窗口,请求拿到结果后再修改窗口地址的方式。需要在键盘回车事件中打开新窗口的推荐使用 form 表单包装并添加 button 的方式,回车触发默认的 submit 事件进行新窗口的打开。

November 4, 2018 · 1 min · jiezi

前后端导出/下载excel方法

一、通过后端处理导出1.) 后端响应头设置前端若想下载一个根据查询参数生成的excel报表文件,需要后端设置请求内容的类型,具体设置如下: response.reset(); response.setContentType(“application/vnd.ms-excel;charset=utf-8”); // 表明是excel类型 //response.setContentType(“application/octet-stream”); // 或设成通用二进制流类型 response.setHeader(“Content-Disposition”, “attachment;filename=test.xls”)); // 将请求的内容存为一个名为test的文件2.) 前端相应的代码正常情况下,用以下两种方法均可:window.open(’/url/download?param=xxx’)window.location = ‘/url/download?param=xxx’ // 不加href,是因为有些浏览器有兼容问题但如果window.open是在一个ajax回调里执行,浏览器会被安全拦截,解决方案:$.ajax({ …. success: function() { var win = window.open() win.location = ‘/url/download?param=xxx’ }})或直接用window.location$.ajax({ …. success: function() { window.location = ‘/url/download?param=xxx’ }})二、前端直接将json数据处理成excel文件具体完整代码如下:<button onclick=‘tableToExcel()’>json导出xls文件</button><script> function tableToExcel() { var jsonData = [{ name: ‘路人甲’, phone: ‘123456’, email: ‘123@123456.com’ }, { name: ‘炮灰乙’, phone: ‘123456’, email: ‘123@123456.com’ }] //列标题 var table = ‘<tr><td>姓名</td><td>电话</td><td>邮箱</td></tr>’ //循环遍历,每行加入tr标签,每个单元格加td标签 jsonData.forEach(function(item) { table += ‘<tr>’; for (let key in item) { //增加t为了不让表格显示科学计数法或者其他格式 table += &lt;td&gt;${item[key] + 't'}&lt;/td&gt; } table += ‘</tr>’; }) //Worksheet名 var worksheet = ‘Sheet1’ //下载的表格模板数据 var template = &lt;html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"&gt; &lt;head&gt; &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt; &lt;!--[if gte mso 9]&gt; &lt;xml&gt; &lt;x:ExcelWorkbook&gt; &lt;x:ExcelWorksheets&gt; &lt;x:ExcelWorksheet&gt; &lt;x:Name&gt;${worksheet}&lt;/x:Name&gt; &lt;x:WorksheetOptions&gt; &lt;x:DisplayGridlines/&gt; &lt;/x:WorksheetOptions&gt; &lt;/x:ExcelWorksheet&gt; &lt;/x:ExcelWorksheets&gt; &lt;/x:ExcelWorkbook&gt; &lt;/xml&gt; &lt;![endif]--&gt; &lt;/head&gt; &lt;body&gt; &lt;table&gt;${table}&lt;/table&gt; &lt;/body&gt; &lt;/html&gt; // 下载模板 window.location.href = ‘data:application/vnd.ms-excel;base64,’ + base64(template) } //输出base64编码 function base64(s) { return window.btoa(unescape(encodeURIComponent(s))) }</script> ...

September 1, 2018 · 1 min · jiezi