较友好的Web文件下载用户体验实例
1.实际需求整理与分析
该问题起源于为公司做的一个B/S架构的游戏静态数据管理工具,其中有一个需求是点击页面上的一些按钮要下载文件,可能根据按钮类型的不同需要转换下载.json、.zip、.xlsx等文件格式,为了好的体验,当时考虑这个功能应做到以下几点:
1.1.页面跳转
下载文件时,页面不会刷新、跳转、添加页面(单页面且所有数据交互都通过ajax,所以要做到这点)
1.2.错误处理
在遇到意外情况,如:文件不存在、服务器异常,同样不允许跳转或者刷新
1.3.错误提示
在1.2的基础上,应能根据错误对用户做出提示。
1.4.需求分析
做到第1点很简单,现代浏览器对于响应头信息Content-Type为application/octet-stream都会提示下载,而不会跳转或者刷新页面。但是直接这样做会带来2,3点的问题,如果文件不存在或者服务器处理出现了异常,则会跳转到404、5**的错误界面。
查了一些方法,综合以后准备利用iframe实现第2点,利用iframe与父页面的交互实现第2点。
2.实现抽象示例
这里以最基本的文件来演示需求的实现。(这里只写了前端的实现,完全实现需要后端处理,对后端的要求这里只做简单介绍)
2.1.功能及文件抽象
这里我根据需求抽象了4个文件:
index.html 提供给用户点击交互的页面(主页)
iframe.html 主页的iframe中加载的页面,该页面body内容默认只有需要加载的js和一个id为json_data,内容为空的div节点(错误提示的时候会有值,后面会介绍),主页面的iframe元素应全程保持隐藏状态
index.js 主页加载的逻辑js文件
iframe.js iframe页面加载的js文件。
2.2.代码实现
下面介绍实例代码,(注:依赖jquery,且只有符合上面需求的功能):
2.2.1.index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Index</title> </head>
<body>
<!-- 这里还至少应该有个下载的按钮或者其他能够提供下载交互的组件 -->
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
2.2.2.index.js
/**
* 文件下载方法
*
* @param string strUrl 下载文件的请求地址
*/
function DownLoad(strUrl) { var download_iframe = $('#download_iframe');
// 没有iframe就添加一个
if (download_iframe.length === 0) {
download_iframe = $('<iframe></iframe>');
download_iframe.attr('id', 'download_iframe');
download_iframe.attr('src', 'iframe.html');
download_iframe.css('display', 'none');
$('body').append(download_iframe);
} else {
// 有的话直接重新载入页面
download_iframe.attr('src','iframe.html?' + Math.random());
}
// 在该iframe加载完成后执行iframe.js内部的Download方法。
var content = download_iframe[0].contentWindow;
download_iframe.one('load', function () {
content.DownLoad(strUrl);
});
} /**
* 处理服务器下载文件返回异常信息
*
* @param object jsonTxt 服务器返回的json信息序列化后的对象
*
*/
function processDownloadErr(jsonTxt) {
alert(jsonTxt.Msg); // 这里只做最简单的弹出处理,实际使用的时候应根据自己项目中有的提示插件进行提示
}
上面代码中会在第一次调用Download时创建一个iframe加载iframe.html;以后再次调用Download则会直接重新加载iframe的内容。
processDownloadErr方法用于处理iframe传过来的错误消息。
2.2.3.iframe.html
一般情况下iframe内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>iframe</title>
</head>
<body>
<div id="json_data"> </div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="iframe.js"></script>
</body>
</html>
有错误或者自定义提示时的内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>iframe</title>
</head>
<body>
<div id="json_data">
{"Msg":"该ID对应的文件不存在!"}
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="iframe.js"></script>
</body>
</html>
2.2.4.iframe.js
/**
* 实际下载文件的方法
*
* @param string strUrl 文件的下载地址
* 该函数可以根据实际需要扩充,比如需要传递参数则再加一个{}类型的形参。
*/
function DownLoad(strUrl) {
// 查找页面上的form表单(因为前面规定,iframe.html中的body默认是空的,所以如果能找到的话必定是下载的form)
var form = $('form');
// 如果找不到,则添加一个
if (form.length == 0) {
form = $("<form>"); // 定义一个form表单
form.attr('style', 'display:none'); // 在form表单中添加查询参数
form.attr('target', ''); // 这里默认给提交自己,
form.attr('method', 'post'); // 这里我设定为post,如果需要自定义的话可以再给Download方法再添加一个参数
}
form.attr('action', strUrl);
$('body').append(form); // 将表单放置在页面body中
form.submit();
} // 默认#json_data内容为空,只有在有错误信息的时候才会获得内容且提交给iframe的顶级节点处理
(function() {
var json_text = $.trim($('#json_data').text());
if (json_text !== '') {
top.processDownloadErr($.parseJSON(json_text).Data);
}
})();
iframe的Download方法被调用时会向body添加一个form表单,并按传入的url提交请求。因为该页面是在iframe中的,所以如果服务器返回404或者5xx等错误也不会引起主页面的跳转。
服务器发现下载文件出现问题的时候,仍返回iframe.html,在其#json_data中设置错误信息(如2.2.3中的内容)。这个时候json_text会获取到值,交由顶层页面处理。
2.2.5.服务器逻辑要求
这里对于服务器逻辑的要求,也就是能够满足在检测文件状态或者参数有误的时候,仍能返回iframe.html,且设置错误信息。
3.总结
上面应该算是不依赖任何插件下,较简单的一种增加浏览器下载文件友好度的实现。因整体项目毕竟为工作项目,所以就不贴真实源码了,以后在自己其他业余时间做的项目中会用到这块逻辑,到时候再贴上博客。只希望本文的一些思路能对大家有帮助。
较友好的Web文件下载用户体验实例的更多相关文章
- web测试总结—用户体验
一.什么是用户体验 用户体验,英文叫做user experience,缩写为UE,或者UX.一个较常见的定义是“指用户访问一个网站或者使用一个产品时的全部体验.他们的印象和感觉,是否成功,是否享受,是 ...
- 改善用户体验 Web前端优化策略总结
前端是庞大的,包括HTML.CSS.Javascript.Image.Flash等等各种各样的资源.前端优化是复杂的,针对方方面面的资源都有不同的方式.那么,前端优化的目的是什么? 1. 从用户角度而 ...
- Web开发中设置快捷键来增强用户体验
从事对日外包一年多以来,发现日本的无论是WinForm项目还是Web项目都注重快捷键的使用,日本人操作的时候都喜欢用键盘而不是用鼠标去点,用他们的话来说"键盘永远比鼠标来的快",所 ...
- Progressive Web App是一个利用现代浏览器的能力来达到类似APP的用户体验的技术——不就是chrome OS吗?
什么是Progressive Web App? Progressive Web App是一个利用现代浏览器的能力来达到类似APP的用户体验的技术,由Google实现,让浏览器打开的网址像APP一样运行 ...
- Web优化躬行记(4)——用户体验和工具
一.用户体验 用户体验(UE/UX)是指一个人使用一个特定产品.系统或服务时的行为.情绪与态度,还包含用户对于系统的功能.易用和效率的感受,因此用户体验在本质上可以视为一个人对于系统的主观感受与主观想 ...
- web设计经验<二>设计华丽的用户体验的6个热门技巧
你是否曾经下载了一个应用,却发现它“很难使用”?对于大多数智能手机用户来说,答案是肯定的. 有趣的是,每四个手机应用中就有一个应用在下载后被“打入冷宫”. 如果一个应用能够吸引一个人下载并且打开它,但 ...
- Django Web开发【6】使用Ajax增强用户体验
Ajax及其优点 Ajax实际上就是指异步Javascript与XML,它包含以下技术: HTML与CSS Javascript XMLHttpRequest XML Ajax技术让客户端与服务器实现 ...
- web开发性能优化---用户体验篇
怎样从技术角度怎样增强用户体验.都是非常多平台都在做的事情,依据个人实际经验碰到几种体验做下总结. 1.降低页面刷新白屏 适当使用ajax技术.改善刷新白屏现象. 2.信息提醒,邮件.站内信.短信在购 ...
- 通过 .NET NativeAOT 实现用户体验升级
前言 TypedocConverter 是我先前因帮助维护 monaco-editor-uwp 但苦于 monaco editor 的 API 实在太多,手写 C# 的类型绑定十分不划算而发起的一个项 ...
随机推荐
- 进入做Mvc项目的时候 返现某个文件夹下面css js png等静态文件都访问不了
原来是我在该文件夹下面添加了一个web.config 里面 静止了所有的文件 直接访问 <system.web> <httpHandlers> <add ...
- 【转帖】驳Jan Baan关于BPM是ERP走向没落起点的说法
驳Jan Baan关于BPM是ERP走向没落起点的说法 Jan Bean在接受畅享网访问的时候提到“BPM是ERP走向没落的一个起点”.“BPM终将取代ERP”,让笔者这样一个在ERP行业待了接近十年 ...
- jQuery Mobile 移动开发中的日期插件Mobiscroll使用说明
近期在移动方面的开发,使用jQuery Mobile ,移动方面的插件不如Web 方面的插件多,选择的更少,有一些需要自己去封装,但功力尚不足啊. 日期插件JQM也提供了内置的,但样式方面不好看,只好 ...
- MariaDB Galera Cluster 10.1 只支持 LINUX ?!
MariaDB Galera Cluster (MariaDB 10.1) 当前只支持:LINUX ! 参考: https://mariadb.com/kb/en/mariadb/getting-s ...
- css3实现进度条的模拟
两种进度条动画的实现: 1.css3,但IE9-不支持. 2.js动画,兼容性好,但没有css3实现的顺畅 Demo: <html> <head> < ...
- coreData 深入理解4 --总结 (线程安全与同步--iOS5 前后对比)
Core Data是iOS中很重要的一个部分,可以理解为基于SQLite(当然也可以是其他的Storage,如In-memory,只是SQLite比较常见)的一个ORM实现,所以有关系数据库的特性,又 ...
- 打开jnlp Faild to validate certificate, the application will not be executed.
今天连jenkins, 本来好好的,只是我在一台机器上一直不断的启动不同的jnlp,绑定不同命名的slave, 然后突然就报错了, 如下截图所示:
- Android 自定义Drawable
1.使用BitmapShader实现图片圆角 public class CornerDrawable extends Drawable { private Paint mPaint; private ...
- .NET 相关工具
加密工具,反DUMP,反调试,反编译,加密代码资源内容,混淆流程,变量.Confuser is a protector/obfuscator for .NET, providing great sec ...
- BAPI 调用相当于BAPI_TRANSACTION_COMMIT 的方法
为什么.net调用SAP的BAPI接口需要调用BAPI_TRANSACTION_COMMIT呢?首先得明白BAPI_TRANSACTION_COMMIT这个BAPI的作用.它功劳很大,在SAP里面很多 ...