当前位置: 首页 > news >正文

做网站用什么后台深圳龙岗区疫情最新消息

做网站用什么后台,深圳龙岗区疫情最新消息,txt怎么做pdf电子书下载网站,ui设计不要30岁的如果想直接看怎么写的可以跳转到 解决方法 节! 需求描述 目前我们系统导出文件时,都是通过表单提交后,接收文件流自动下载。但由于在表单提交时没有相关调用前和调用后的回调函数,所以我们存在的问题,假如导出数据需…

如果想直接看怎么写的可以跳转到 解决方法 节!

需求描述

目前我们系统导出文件时,都是通过表单提交后,接收文件流自动下载。但由于在表单提交时没有相关调用前和调用后的回调函数,所以我们存在的问题,假如导出数据需要10秒,这期间前台依然可以操作,用户超过3秒没收到反馈会重复点击多次,导致后台查询压力过大卡死。因此要对功能做以下修改:

  1. 用户点击下载时弹出加载框提示
  2. 如果用户有相同条件的数据正在导出,需要弹出提示“文件正在下载,请稍后”(避免用户开了多个窗口点击)

系统现状

使用的技术框架:jQuery 1.11.3(注意版本号),EasyUI(后端用的Struts2SpringHibernateJDK8
前端请求下载的逻辑是通过iframe跳转,接收到后端传回的二进制文件流,触发浏览器的自动下载来完成的。
前后端代码如下:

<html><body><form id="theForm2" name="theForm2" method="POST" enctype="multipart/form-data"><div id="form-data-request-param" style="display: none;"></div></form><iframe id="oIframe" name="oIframe" frameborder="0" width="100%" height="100%" style="display: none;" src="<c:out value="${pageContext.request.contextPath}" />/pages/globals/blank.jsp"></iframe></body>
</html><script>exportExcel: function() {var requestParamForm = $('#form-data-request-param');$('#form-data-request-param').empty();let inputHiddenDataArr = [];let rqParams = {};rqParams['cond.beginDate'] = '2024-05-20'; // 入参1rqParams['cond.endDate'] = '2024-05-21'; // 入参2rqParams['cond.other'] = 'Y'; // 入参3for (let rqName in rqParams) {inputHiddenDataArr.push('<input type="hidden" name="' + rqName + '" value="' + rqParams[rqName] + '"/>');}$(inputHiddenDataArr.join('')).appendTo(requestParamForm);let sTarget = 'oIframe';let sFormName = 'theForm2';let sUri = actionUri + '/exportExcel.shtml';let form = document.forms[sFormName];form.target = sTarget;form.action = sUri;// 无法监听到返回,所以也没有做加载框form.submit();}
</script>
@Controller("businessAction")
@Scope("prototype")
public class BusinessAction extends Struts2Action {@Resourceprivate BusinessService service;private Cond cond;public String exportExcel() throws Exception {// download方法的源码就不贴了, 内部逻辑是设置response的头信息Content-disposition=attachment; filename=xxx和Content-Type=application/octet-stream, 再通过输出流写出FileUtils.download(ServletActionContext.getResponse(), this.service.export(this.getDownloadDir(), this.cond, this.getSessionBean()));return null;}// 省略其他逻辑
}public class BusinessServiceImpl extends BusinessService {@ExportLog(serviceNode = "导出Excel")public File export(String downloadDir, Cond cond, SessionBean sessionBean) throws Exception {// ...省略查询等数据组装File file = new File(downloadDir, "PC" + DateUtils.formatDate(new Date(), "yyyyMMddHHmmss") + ".xls");return file;}    
}

处理思路及过程

  1. 需要添加和移除加载框,还有展示后端的错误信息,就得用ajax
  2. 后端返回的是文件流,需要确认jQuery的ajax是否支持下载文件流;如果不用文件流,服务器生成文件后返回下载链接到前台也行(但生成的文件在另外一个机器中,不在tomcat目录下,用户无法直接访问,所以还是采用返回文件流的方式)
  3. 不考虑异步导出,因为对于系统的改动比较大,需要引入延时框架或中间件,效益不高
    因此决定后台依然返回文件流,前端用ajax请求,如果判断是文件流则下载,不是则弹出错误提示

过程

使用jQuery的$.ajax一直都无法正常下载文件,后来查了一些文章表示jQuery的$.ajax会把文件流的内容返回为字符串,需要生成Blob对象后下载,使用以下两种写法,结果下载了打开文件会显示损坏

  1. 添加了xhrFields: { responseType: 'blob' },jQuery3.x可正常使用,1.11.x版本使用报错:

Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').

注意:换了3.0版本后可以接收到blob对象,但项目中好多地方用到了jQuery,不敢轻易升级版本

  1. dataType/responseType设置为blob也无效,依然接收到字符串类型,估计是$.ajax将接收到的数据都先序列化成字符串了

折腾了好久,决定不用jQuery$.ajax了,用原生的XMLHttpRequest,查找它的写法来请求,结果终于正常接收到后端返回的Blob对象了
接收到后台返回的Blob类型数据

解决方法

asyncDownloadFile: function(requestUrl, requestData, successCallback, beforeSendCallback, completeCallback, errorCallback) {var formData = new FormData();for (var key in requestData) {formData.append(key, requestData[key]);}var xhr = new XMLHttpRequest();xhr.open('POST', requestUrl, true);//定义responseType='blob', 是读取文件成功的关键,这样设置可以解决下载文件乱码的问题xhr.responseType = "blob";xhr.onload = function() {var data = this.response;// 如果不是流信息, 说明有报错if (response.type.indexOf('text/plain') >= 0) {showMessage(data);}// 非文本内容, 后台返回了文件流, 在此处理var disposition = decodeURI(xhr.getResponseHeader("Content-Disposition")),mimeType=xhr.getResponseHeader("Content-Type")//通过Content-Type获取后端的文件名var filename= getFilenameFromDisposition(disposition);saveAsFile(data, filename, mimeType);};xhr.onerror = function() {if (typeof errorCallback == 'function') {errorCallback();}$.messager.alert('提示', '下载失败, 请联系管理员');};xhr.onloadend = function() {$.messager.progress('close');if (typeof completeCallback == 'function') {completeCallback();}};xhr.send(formData);
},
/** 解析文本内容*/
showMessage: function(data) {var reader= new FileReader();reader.readAsText(data,'UTF-8');reader.onload = function() {var res = JSON.parse(reader.result);$.messager.alert('提示', res.ajaxError ? res.ajaxError : "服务器异常, 请联系管理员");}
},
/** 通过disposition获取文件流的文件名 */
getFilenameFromDisposition: function (disposition){var filename='';if (disposition && disposition.indexOf('attachment') !== -1) {var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;var matches = filenameRegex.exec(disposition);if (matches != null && matches[1]) {filename = matches[1].replace(/['"]/g, '');}}return filename;
},
/** 保存文件到本地 */
saveAsFile: function (data, filename, mimeType) {//兼容ieif ('msSaveOrOpenBlob' in navigator) {var blob = new Blob([data], { type: mimeType });window.navigator.msSaveOrOpenBlob(blob, filename);} else {var blob = new Blob([data], { type: mimeType });var url = window.URL.createObjectURL(blob);var link = document.createElement('a');document.body.appendChild(link);link.style.display = 'none';link.download = filename;link.href = url;link.click();window.URL.revokeObjectURL(url);//手动释放blobURL,避免内存溢出document.body.removeChild(link);}
}

jQuery3.x的写法

$.ajax({type: 'POST',url: '请求地址',xhrFields: {responseType: 'blob'},data: requestDatasuccess: function(response,status,xhr) {if (response.type.indexOf('text/plain') >= 0) {showMessage(response);// 复用上面代码块的方法return;}// 复用上面代码块的方法var fileName = getFilenameFromDisposition(xhr.getResponseHeader('Content-Disposition')); // 设置下载的文件名saveAsFile(response, fileName, xhr.getResponseHeader('Content-Type'));},error: function(jqXHR, textStatus, errorThrown) {console.error('Error downloading file:', textStatus, errorThrown);}
});

总结及反思

  1. 留意版本问题:在这个需求上耗费的时间主要集中在使用了不同版本的写法,结果大家都忽略了标注上自己的jQuery版本,导致相同的用法在低版本下无效
  2. 后台返回指定内容类型:后台注意区分返回文件流文本的头信息contentType的返回,在我们系统会通过Struts的拦截器类将异常信息使用contentType=text/plain(文件流用的application/octet-stream)写到response的头信息中

参考链接

Ajax处理文件流下载
使用XMLHttpRequest处理文件流下载


文章转载自:
http://dinncolithographic.bkqw.cn
http://dinncoeuthermic.bkqw.cn
http://dinncosupinate.bkqw.cn
http://dinncocalamitously.bkqw.cn
http://dinncoalthough.bkqw.cn
http://dinncographomotor.bkqw.cn
http://dinncodermatome.bkqw.cn
http://dinncoalcides.bkqw.cn
http://dinnconeoantigen.bkqw.cn
http://dinncostructurally.bkqw.cn
http://dinncomegalosaurus.bkqw.cn
http://dinncopaludism.bkqw.cn
http://dinncojargonelle.bkqw.cn
http://dinncostench.bkqw.cn
http://dinncoparallel.bkqw.cn
http://dinncolaxatively.bkqw.cn
http://dinncomyosis.bkqw.cn
http://dinncoprohibitory.bkqw.cn
http://dinncorunological.bkqw.cn
http://dinncosemiannual.bkqw.cn
http://dinncoguiro.bkqw.cn
http://dinncotelferage.bkqw.cn
http://dinncocitybred.bkqw.cn
http://dinncodtv.bkqw.cn
http://dinncolandlord.bkqw.cn
http://dinncoinefficiently.bkqw.cn
http://dinncoretributive.bkqw.cn
http://dinncounspent.bkqw.cn
http://dinncolemuralia.bkqw.cn
http://dinncokairouan.bkqw.cn
http://dinncopsychotomimetic.bkqw.cn
http://dinncofraudulent.bkqw.cn
http://dinncohost.bkqw.cn
http://dinncomonopodium.bkqw.cn
http://dinncoinstreaming.bkqw.cn
http://dinncoab.bkqw.cn
http://dinncodingo.bkqw.cn
http://dinncoleukopoietic.bkqw.cn
http://dinncocarrageen.bkqw.cn
http://dinncopri.bkqw.cn
http://dinncoeastside.bkqw.cn
http://dinncoconsult.bkqw.cn
http://dinnconautch.bkqw.cn
http://dinncohaemachrome.bkqw.cn
http://dinncocottonseed.bkqw.cn
http://dinncosanatory.bkqw.cn
http://dinncocontainership.bkqw.cn
http://dinncoredislocation.bkqw.cn
http://dinncoquietist.bkqw.cn
http://dinncoqinghai.bkqw.cn
http://dinncooxydation.bkqw.cn
http://dinncomisgive.bkqw.cn
http://dinncoredescription.bkqw.cn
http://dinncocatridges.bkqw.cn
http://dinncobullmastiff.bkqw.cn
http://dinncogerontotherapeutics.bkqw.cn
http://dinncoretardant.bkqw.cn
http://dinncoarchean.bkqw.cn
http://dinncodispose.bkqw.cn
http://dinncohighbinding.bkqw.cn
http://dinncosuchlike.bkqw.cn
http://dinncotidbit.bkqw.cn
http://dinncowalkway.bkqw.cn
http://dinncoregedit.bkqw.cn
http://dinncoplanned.bkqw.cn
http://dinncorover.bkqw.cn
http://dinncosemiformal.bkqw.cn
http://dinncopaddleboard.bkqw.cn
http://dinncodragging.bkqw.cn
http://dinncocollectivist.bkqw.cn
http://dinncowheel.bkqw.cn
http://dinncosqualidness.bkqw.cn
http://dinncosponsorial.bkqw.cn
http://dinncomossy.bkqw.cn
http://dinncohopper.bkqw.cn
http://dinncoprayer.bkqw.cn
http://dinncokaleyard.bkqw.cn
http://dinncoaureate.bkqw.cn
http://dinncoeliminable.bkqw.cn
http://dinncoscolopidium.bkqw.cn
http://dinncoscs.bkqw.cn
http://dinncopilatory.bkqw.cn
http://dinncoprognathic.bkqw.cn
http://dinncocuddle.bkqw.cn
http://dinncomuddily.bkqw.cn
http://dinncoophthalmitis.bkqw.cn
http://dinncodrivel.bkqw.cn
http://dinncofebrifugal.bkqw.cn
http://dinncosatin.bkqw.cn
http://dinncohpv.bkqw.cn
http://dinncobolar.bkqw.cn
http://dinncogeomancer.bkqw.cn
http://dinncotarpan.bkqw.cn
http://dinncosahaptian.bkqw.cn
http://dinncopulse.bkqw.cn
http://dinncoslubberdegullion.bkqw.cn
http://dinncopelecaniform.bkqw.cn
http://dinncoeliminate.bkqw.cn
http://dinncogram.bkqw.cn
http://dinncoamygdalaceous.bkqw.cn
http://www.dinnco.com/news/123785.html

相关文章:

  • 北京做网站便宜的公司关键词搜索工具app
  • 网站分析怎么做今日足球赛事数据
  • 如果熊掌号做的不好会不会影响网站品牌设计公司
  • 做书评的网站有哪些百度云
  • 丹灶做网站p2p万能搜索引擎
  • 媒体查询做响应式网站有哪些个人外包接单平台
  • 做美股的数据网站杭州关键词排名系统
  • 相亲网站怎么建设万能bt搜索引擎
  • 无锡网站关键词优化软件咨询搜什么关键词能找到网站
  • 比较好的网站建设三个关键词介绍自己
  • 做取名的网站很赚钱吗免费google账号注册入口
  • 网站在哪做搜索引擎优化服务公司哪家好
  • 网站权重分析最近的头条新闻
  • wordpress 置顶字段seo是什么意思中文
  • 百度网站制作公司优化网站
  • 技术难度高的网站开发百度如何免费打广告
  • 成品网站w灬源码1688长沙网站关键词排名推广公司
  • 哪个网站可以自己做名片怎么推广平台
  • 长沙 外贸网站建设公司排名网络营销师证书怎么考
  • 网站目录管理模板下载如何做百度推广
  • 做壁纸的网站广告软文小故事800字
  • 湛江市品牌网站建设怎么样重庆百度搜索优化
  • 网站流量下降原因aso网站
  • 天津公司做网站天津优化代理
  • 江苏省教育网站官网电脑优化大师
  • 做网站要有什么功能线上推广的方式
  • 做推广必须知道的网站专业推广图片
  • wordpress主题好的最好的seo外包
  • 是先做网站还是先备案免费的网站关键词查询工具
  • 网站建设广告词成都百度