javascript页面无跳转下载
一、问题说明
现在前端页面为

相应的代码为:(逻辑在downloadButtonClicked方法中实现)
downloadDemo.jsp(路径为src\main\webapp\datadisplay\downloadDemo.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件下载demo</title>
</head>
<body>
<input type="hidden" id="path" value="${pageContext.request.contextPath}"/>
<h3>无跳转文件下载</h3>
<input type="button" value="下载" id="downloadBtn" onclick="downloadFile('测试下载.txt')"/>
<script src="http://libs.baidu.com/jquery/1.8.3/jquery.js"></script>
<script type="text/javascript">
function downloadFile(resourceName) {
var url = $("#path").val() + "/datadisplay/testDownload.action?resourceName=" + resourceName;
downloadButtonClicked(url);
}
function downloadButtonClicked(url) {
}
</script>
</body>
</html>
二、解决过程
我看到一般的解决方法都是
window.location.href=下载的url
但是我这个页面在downloadButtonClicked方法中如果这样写,一点击下载按钮,页面直接就跳转了
我想到最近看的后台管理系统(若依)里的导出excel用的就是window.location.href,那为什么整个页面没有跳转呢?

咱们先debug,看看页面结构再说


看到这里,我突然明白了,这段改的就是iframe的src
这就给我提供了一个思路:通过改iframe的src来实现下载时页面不用跳转
但现在我的页面没有iframe,该怎么办?那就给个隐藏的iframe,用来给下载改地址使用,代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件下载demo</title>
</head>
<body>
<input type="hidden" id="path" value="${pageContext.request.contextPath}"/>
<h3>无跳转文件下载</h3>
<input type="button" value="下载" id="downloadBtn" onclick="downloadFile('测试下载.txt')"/>
<iframe style="display:none;" name="hiddenIframe" id="hiddenIframe"></iframe>
<script src="http://libs.baidu.com/jquery/1.8.3/jquery.js"></script>
<script type="text/javascript">
function downloadFile(resourceName) {
var url = $("#path").val() + "/datadisplay/testDownload.action?resourceName=" + resourceName;
downloadButtonClicked(url);
}
function downloadButtonClicked(url) {
// 这里需要加上encodeURI,因为ie不会对中文自动转码
$("#hiddenIframe").attr("src", encodeURI(url));
}
</script>
</body>
</html>
这样就ok了(在chrome、firefox、ie下测试均能正常使用)
顺便补充下:1. 我开始是先google搜索了“javascript no redirect page download”,然后找到一个比较近似的结果(https://stackoverflow.com/questions/1066452/easiest-way-to-open-a-download-window-without-navigating-away-from-the-page)。思路就是创建一个虚拟的a标签,该标签指向iframe,然后点击a标签就相当于更改了iframe的src,这个思路已经非常接近我最终用的方法了

在我这边,就是写成
function downloadButtonClicked(url) {
var elem = document.createElement("a");
elem.href = url;
elem.target = "hiddenIframe";
elem.click();
}
后来没使用这个方法,因为在firefox和ie下没有效果
2. 补充一个之前用过的方法,判断当前页面是否在iframe中
self!=top(返回true,说明在iframe中;false,表示不在iframe中)
https://www.cnblogs.com/zycbloger/p/6196493.html
附后台下载代码(我用的是struts2,这个其实跟框架无关,提供下只是方便各位重现):
java代码
package com.kittycoder.datadisplay.action;
import com.opensymphony.xwork2.ActionSupport;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
/**
* Created by shucheng on 2019-6-12 下午 20:56
* 下载action
*/
public class DownloadAction {
private String resourceName;
private InputStream inputStream;
private String downloadFileName;
// 下载文件
public String downloadFile() {
try {
String content = "测试文件下载";
ByteArrayInputStream stream = new ByteArrayInputStream(
content.getBytes(StandardCharsets.UTF_8));
setDownloadFileName(resourceName); // 设置下载文件名
setInputStream(stream); // 设置下载文件流
} catch (Exception e) {
e.printStackTrace();
}
return ActionSupport.SUCCESS;
}
public String getResourceName() {
return resourceName;
}
public void setResourceName(String resourceName) {
this.resourceName = resourceName;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
// 解决下载文件名中文乱码问题
public String getDownloadFileName() {
try {
downloadFileName = new String(downloadFileName.getBytes("gbk"), "iso-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downloadFileName;
}
public void setDownloadFileName(String downloadFileName) {
this.downloadFileName = downloadFileName;
}
}
struts2配置文件 struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="strutsDemo" extends="json-default" namespace="/datadisplay">
<!-- 测试struts下载 -->
<action name="testDownload" class="com.kittycoder.datadisplay.action.DownloadAction" method="downloadFile">
<result name="success" type="stream">
<param name="contentType">multipart/form-data</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">
attachment;filename="${downloadFileName}"
</param>
<param name="bufferSize">2048</param>
</result>
</action>
</package>
</struts>
这里配置文件中有个需要注意的地方(不是struts2特有的):contentDisposition设置成attachement,浏览器才能让文件直接就能下载
这个其实就是设置响应头里的Content-Disposition,对servlet、springmvc也是一样的。浏览器里的默认设置为inline(能显示则显示,不能显示则下载),attachement就是以附件形式下载
参考链接:
更多推荐


所有评论(0)