下载附件谷歌浏览器报:ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION

本文讨论了如何在WebAction中优化代码,解决文件下载功能在不同浏览器下的兼容性问题,特别是针对IE、360、谷歌浏览器的支持情况进行了详细分析,并提供了相应的解决方案。
//修改前webAction代码
package com.web.action;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;


import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;

public class FileDownload implements Action {

private String fileName;// 初始的通过param指定的文件名属性
private String inputPath;// 指定要被下载的文件路径

public InputStream getInputStream() throws Exception {
// 通过 ServletContext,也就是application 来读取数据


ServletActionContext.getResponse().addHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(getDownloadFileName(),"utf-8"));
//return ServletActionContext.getServletContext().getResourceAsStream("/upload"+"/"+
//inputPath+"/"+getDownloadFileName());
//return ServletActionContext.getServletContext().getResourceAsStream("/upload"+"/"+
//inputPath+"/"+getDownloadFileName());



InputStream iStream=new FileInputStream("D:/ftoa/upload/"+inputPath+"/"+getDownloadFileName());
//InputStream iStream=new FileInputStream( ServletActionContext.getRequest().getRealPath("externalOper/files")+"/"+getDownloadFileName());

return iStream;
//String dstPath ="d:/upload/" + this.getSavePath()+ "/" + tempUrl;
}

public void setInputPath(String value) {
inputPath = value;
}

public void setFileName(String fileName) {
this.fileName = fileName;
}

/** 提供转换编码后的供下载用的文件名 */
public String getDownloadFileName() {
String downFileName = fileName;
try {
downFileName = new String(downFileName.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downFileName;
}

public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}

}
//--------------------------------------------
//修改前Strut2配置
<action name="fileDownload" class="fileDownload">
<param name="inputPath">/各类地址.txt</param>
<!-- 初始文件名 -->
<param name="fileName">各类地址.txt</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream;</param>
<param name="inputName">inputStream</param>
<param name="bufferSize">4096</param>
</result>
</action>
//----------------------------------
//以上做法只有IE支持,360,谷歌都不支持附件下载。
//谷歌浏览报:
//收到了来自服务器的重复标头

//隐藏详细信息
//来自服务器的响应包含重复标头。此问题通常是由于网站或代理配置不正确导致的。
//只有网站或代理管理员才能解决此问题。
//错误代码:ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
//----------------------------------------
//修改后:javaAction代码
package com.web.action;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;


import com.opensymphony.xwork2.Action;

public class FileDownload implements Action {

private String fileName;// 初始的通过param指定的文件名属性
private String inputPath;// 指定要被下载的文件路径

public InputStream getInputStream() throws Exception {
// 通过 ServletContext,也就是application 来读取数据


// ServletActionContext.getResponse().addHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(getDownloadFileName(),"utf-8"));
//return ServletActionContext.getServletContext().getResourceAsStream("/upload"+"/"+
//inputPath+"/"+getDownloadFileName());
//return ServletActionContext.getServletContext().getResourceAsStream("/upload"+"/"+
//inputPath+"/"+getDownloadFileName());



InputStream iStream=new FileInputStream("D:/ftoa/upload/"+inputPath+"/"+getDownloadFileName());
//InputStream iStream=new FileInputStream( ServletActionContext.getRequest().getRealPath("externalOper/files")+"/"+getDownloadFileName());

return iStream;
//String dstPath ="d:/upload/" + this.getSavePath()+ "/" + tempUrl;
}

public void setInputPath(String value) {
inputPath = value;
}

public void setFileName(String fileName) {
this.fileName = fileName;
}

/** 提供转换编码后的供下载用的文件名 */
public String getDownloadFileName() {
String downFileName = fileName;
try {
downFileName = new String(downFileName.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downFileName;
}

public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}

public String getFileName() throws UnsupportedEncodingException {
return URLEncoder.encode(getDownloadFileName(),"utf-8");
}


}
//------------------------------------------------------------
//-------struts2配置----
<action name="fileDownload" class="fileDownload">
<param name="inputPath">/各类地址.txt</param>
<!-- 初始文件名 -->
<param name="fileName">各类地址.txt</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream;</param>
<param name="inputName">inputStream</param>
<!-- 下载文件处理方法 -->
<param name="contentDisposition">attachment;filename=${fileName}</param>
<param name="bufferSize">4096</param>
</result>
</action>
-----------------------------------
/ //经测试谷歌,IE,360浏览器都支持
---------------jsp代码-------------------------
[url=javascript:download('<s:property value=]','<s:property value="#f[0]" />')"><s:property value="#f[0]" />[/url];
----------------------------
<form action="fileDownload" name="downloadfrom" >
<input type="hidden" name="inputPath" value="" />
<input type="hidden" name="fileName" value="" />
</form>
-------------js代码--------------------------
function download(fileurl,filename){
document.forms["downloadfrom"].inputPath.value=fileurl;
document.forms["downloadfrom"].fileName.value=filename;
document.forms["downloadfrom"].submit();
}
-----------------------------------------------
<template> <div class="form-container"> <div style="margin-left: 0%"> <el-card style="width: 100%;" v-loading="listLoading"> <div> <h1 style="text-align: center">上传log</h1> <div style="width: 100%; padding-top: 20px;"> <div class="search_form"> <!--querySearch里面的参数需要写成sql里面的字段加_的那种,而且下划线后面首字母必须大写--> <el-form :inline="true" size="small" label-width="300px"> <el-form-item label="机型项目代号:"> <el-autocomplete class="input-width-class" @keypress.native.enter="onEnterPress" v-model="uploadData.fieldData.project" :fetch-suggestions="(queryString, cb)=>querySearch(queryString,cb,'project')" placeholder="请输入内容" value-key="projectCode" clearable></el-autocomplete> <!-- <el-input class="input-width-class" v-model="appQueryParam.owner" placeholder="Platform" clearable></el-input>--> </el-form-item> </el-form> </div> </div> <div class="upload-file-log" v-show="uploadData.fieldData.project" style="padding-left: 25%;width: 49%"> <el-upload ref="upload" drag multiple :limit="5" action="http://xxx.xxx.xxx/personality/uploadExcel" :on-change="handleChange" :before-remove="beforeRemove" :on-exceed="handleExceed" :file-list="fileList" :http-request="uploadFile" :on-remove="remove" :auto-upload="false"> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或点击上传</div> <div slot="tip" class="el-upload__tip" style="text-align: left ;">文件大小不超过400m</div> <!-- <div slot="tip" class="el-upload__tip" style="text-align: left ;">只能上传xlsx文件,且不超过100m</div>--> </el-upload> </div> <div style="text-align: center;padding-top: 5%"> <el-button type="primary" size="medium" @click="submitUpload()">上传</el-button> <el-button type="" size="medium" @click="emptyData()">清空</el-button> </div> <div style="padding-top: 5%;font-size: 14px;margin-bottom: 20px;margin-left: 10%"> <h3>填写说明:</h3> <p> <span style="color: red">*</span> 原"tz -t"类型解密,上传 /data/vendor/diag 下的 last_tzlog_x 文件,请同时上传同文件夹下 last_tzlog_key_x 文件,不能改名 </p> <p> <span style="color: red">*</span> 豆荚类型解密必须上传名为dumpstate_board.txt文件 ,请同时上传 bugreport 文件 </p> <p> <span style="color: red">*</span> "tz -b"类型只需 上传解析dumpstate_board.txt文件 </p> <p> <span style="color: red">*</span> "tz -m" log需上传minidump.gz,解析出明文的TZ_log即out_tz_parsed.txt用于分析 </p> <p> <span style="color: red">*</span> 0-trusty的生成还有点小麻烦. 步骤: adb pull /data/ylog; cd ylog; chmod a+x analyzer.py; ./analyzer.py; cd 解密目录: eg:000-0218_055400_poweron 上传0-trusty.log </p> <p> <span style="color: red">*</span> 当你遇到问题请联系管理员: wushubo@xiaomi.com </p> </div> </div> </el-card> </div> </div> </template> <script> import {uploadLogs} from "../../api/decryptLog" import {getProjectColumnData, queryProjectInfoByPageList} from "../../api/projectInfo"; export default { name: "upload", data() { return { columns: [], columnData: {}, fileData: '', // 文件上传数据(多文件合一) fileList: [], // upload多文件数组 uploadData: { fieldData: { project: '', } }, listLoading:false, logTypes: [ {name:"qsee", value:"qsee"}, {name:"tz_log", value:"tz_log"}, {name:"qsee_8550", value:"qsee_8550"}, {name:"tz_log_8550", value:"tz_log_8550"}, {name:"tz -t 8350", value:"tz_t_8350"}, {name:"tz -b 8350", value:"tz_b_8350"}, {name:"tz -t 8450", value:"tz_t_8450"}, {name:"tz -b 8450", value:"tz_b_8450"}, {name:"tz -m 8450", value:"tz_m_8450"}, {name:"MITEE", value:"MITEE"}, {name:"beanpod", value:"beanpod"}, {name:"beanpod_19", value:"beanpod_19"}, {name:"modem", value:"modem"}, {name:"tz -t 8550", value:"tz_t_8550"}, {name:"tz -b 8550", value:"tz_b_8550"}, {name:"tz -m 8550", value:"tz_m_8550"}, // {name:"elf", value:"elf"}, ], logFileNames:{ "qsee":[".log"], "tz_log":[], "tz -t 8350":[], "tz -t 8450":[], "tz -b 8350":[], "tz -b 8450":[], "MITEE":[".log"], "beanpod":["dumpstate_board.txt"], "modem":[".elf"], }, index:0 } }, computed: { header:function (){ return { "ContentType": 'multipart/form-data', }; } }, methods:{ handleSelect(item) { this.onEnterPress() }, onEnterPress() { //清空时候会把光标遗留到input里面造成可以输入但是没有建议的问题,手动把光标挪出去 document.activeElement.blur() }, querySearch(queryString, cb, filterName) { console.log(this.columns.indexOf(filterName.replace("_", "")) == -1) if (this.columns.indexOf(filterName.replace("_", "")) == -1) { getProjectColumnData(filterName) .then((res) => { filterName = filterName.replace("_", "") this.columns.push(filterName) this.columnData[filterName] = res.data.data console.log(this.columnData) var results = queryString ? this.columnData[filterName].filter(this.createFilter(queryString, filterName)) : this.columnData[filterName]; cb(results); }) .catch((err) => { this.$message.error(err) }) } else { filterName = filterName.replace("_", "") var results = queryString ? this.columnData[filterName].filter(this.createFilter(queryString, filterName)) : this.columnData[filterName]; cb(results); } }, createFilter(queryString, filterName) { return (tableData) => { console.log(tableData[filterName]) console.log(tableData) console.log(filterName) filterName = filterName == "project" ? "projectCode" : filterName return (tableData[filterName].toLowerCase().indexOf(queryString.toLowerCase()) >= 0); }; }, // beforeUpload(file){ // } uploadSuccess(response, file){ if (response.code==200){ this.$message.success("批量添加成功") }else{ this.$message.error(response.message) } }, uploadError(err, file){ this.$message.error(err) }, uploadProgress(file){ }, // 上传文件 uploadFile(file) { // this.fileList.forEach((v,k)=>{ // console.log(this.fileData) // console.log(v.name) // if(this.fileData.get("file"+k)==undefined) // this.fileData.a("file"+k, v); // append增加数据 // }) // if(this.fileData.get("files")==undefined){ console.log(file.file) console.log(this.fileList[0].raw) this.fileData.append("ceshi",this.fileList[0].raw) this.fileData.append('file'+this.index, file.file); // append增加数据 this.index++; // } }, // 上传到服务器 submitUpload() { let fieldData = this.uploadData.fieldData; // 缓存,注意,fieldData不要与fileData看混 if (fieldData.project === '') { this.$message({ message: '请选择上传的log类型', type: 'warning' }) } else if (this.fileList.length === 0) { this.$message({ message: '请先选择文件', type: 'warning' }) } else { const isLt100M = this.fileList.every(file => file.size / 1024 / 1024 < 400); if (!isLt100M) { this.$message.error('请检查,上传文件大小不能超过400MB!'); } else { this.fileData = new FormData(); // new formData对象 var project; if (this.uploadData.fieldData.project != null && this.uploadData.fieldData.project != undefined) { if (this.uploadData.fieldData.project.indexOf("-") != -1) { project = this.uploadData.fieldData.project.split("-")[0] } else { project = this.uploadData.fieldData.project } } else { //用户清空机型输入框点击回车的情况 if (this.project != '') { this.project = '' } } // this.$refs.upload.submit(); // 提交调用uploadFile函数 this.fileData.append('project', project); // 添加log类型 //check上传的logtype和文件,并且添加到fileData if(!this.checkFile()) { return } this.listLoading=true; uploadLogs(this.fileData).then( res=>{ if(res.code && res.code == 500) { this.fileList = []; this.index = 0; this.listLoading=false this.$message.error(res.message); return; } console.log(res.headers['content-disposition'].split(';')[2].split('=')[1]) console.log(res.headers['content-disposition'].split(';')[2].replaceAll("\"","")) console.log(res.headers['content-disposition']) const fileName = decodeURI(res.headers['content-disposition'].split(';')[2].split('=')[1].replaceAll("\"","")) // 文件名 const data = res.data // Blob数据对象 const uA = window.navigator.userAgent const isIE = /msie\s|trident\/|edge\//i.test(uA) && !!('uniqueID' in document || 'documentMode' in document || 'ActiveXObject' in window || 'MSInputMethodContext' in window) let url = window.URL.createObjectURL(new Blob([data])) let link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', fileName) document.body.appendChild(link) // 兼容IE if (isIE) { navigator.msSaveBlob(new Blob([data]), fileName) } else { link.click() } this.fileList = []; this.index = 0; this.listLoading=false } /* (response) => { if (response.data.code === 0) { this.$message({ message: "上传成功", type: 'success' }); this.fileList = []; } else { this.$message({ message: response.data.desc, type: 'error' }) } }*/ ) .catch(err => { this.$message.error("解密失败,请重新检查后操作或者联系管理员:wushubo") // this.$message.error(err.data) this.fileList = []; this.index = 0; this.listLoading = false }); } } }, //移除 // handleRemove(file, fileList) { // this.fileList = fileList; // alert(this.$confirm(`确定移除 ${ file.name }?`)); // return this.$confirm(`确定移除 ${ file.name }?`); // }, beforeRemove(file, fileList) { return this.$confirm(`确定移除 ${file.name}?`) }, // 选取文件超过数量提示 handleExceed(files, fileList) { this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`); }, //监控上传文件列表 handleChange(file, fileList) { let existFile = fileList.slice(0, fileList.length - 1).find(f => f.name === file.name); if (existFile) { this.$message.error('当前文件已经存在!'); fileList.pop(); } this.fileList = fileList; }, checkFile() { var project = this.uploadData.fieldData.project if (this.fileList.length == 2) { if ([this.fileList[0].name, this.fileList[1].name].includes("dumpstate_board.txt")) { if (this.fileList[0].name == "dumpstate_board.txt") { console.log("file0 --------------" + this.fileList[0].name) console.log("file1 --------------" + this.fileList[1].name) this.fileData.append("file0", this.fileList[0].raw); this.fileData.append("file1", this.fileList[1].raw); } else { console.log("file0 --------------" + this.fileList[1].name) console.log("file1 --------------" + this.fileList[0].name) this.fileData.append("file0", this.fileList[1].raw); this.fileData.append("file1", this.fileList[0].raw); } } else if ([this.fileList[0].name, this.fileList[1].name].includes("last_tzlog_key")) { if (this.fileList[1].name == "last_tzlog_key") { this.fileData.append("file0", this.fileList[0].raw); this.fileData.append("file1", this.fileList[1].raw); } else { this.fileData.append("file0", this.fileList[1].raw); this.fileData.append("file1", this.fileList[0].raw); } } else { this.$message.warning("请查看填写说明") return false } } else if (this.fileList.length == 1) { console.log("file0 --------------" + this.fileList[0].name) this.fileData.append("file0", this.fileList[0].raw); } else { this.$message.warning("请确认上传文件数量是否正确") return false } return true }, emptyData() { this.uploadData.fieldData.project = ""; this.fileList = []; }, remove(file, fileList) { this.fileList = fileList } } } </script> <style scoped> .form-container { margin: 0px auto; width: 800px; padding-top: 40px; /*position: absolute;*/ /*left: 0;*/ /*right: 0;*/ /*width: 720px;*/ /*padding: 35px 35px 15px 35px;*/ /*margin: 20px auto;*/ /*width: 800px;*/ /*border: 1px solid #ebeef5;*/ /*height: 50%;*/ } .el-upload__tip{ text-align: right; } .tip_text{ float: left; line-height: 28px; width: 200px; } /*尽量不要和其他组件里面的class同名,会导致编译之后放在同一个css文件里面class被替换问题*/ .upload-file-log{ margin-top: 50px; } p{ margin-top: 15px; } .input-width-class{ width: 250px; } </style> // WEBPACK FOOTER // // src/view/decrypt_log/upload.vue
10-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值