核心提示:下载文件组件,可以处理文件下载成功和失败。github地址:https://github.com/theanarkh/download/download.js/***author cybdate 12...
下载文件组件,可以处理文件下载成功和失败。github地址:https://github.com/theanarkh/download/
download.js
/*** author cyb date 12/12/2016 22:55 created by sublime3 ***/ /* element 点击触发下载的元素,任何可点击的元素都可以,一般用button和a标签 url 下载的url,可以是静态的,也可以是动态生成的,类型为字符串或函数 condition 点击下载时的额外条件,一般用于按条件导出数据到excel文件等,类型为对象 callback 下载出错时的回调函数 beforeDownload 点击下载之前需要执行的函数,可用于鉴权,不合法的用户不能下载 使用该组件的前提是下载的url和代码所在页面的url是同源或者能够通过设置document.domain实现iframe和目标页面互相访问, 因为frameElement.callback中的frameElement只有同源,设置了document.domain,页面本身就是最上层的页面时才有值,其他情况下都是null */ function Download(config) { this.element = config.element; this.url = config.url; this.condition = config.condition; this._callback = config.callback; this._beforeDownload = config.beforeDownload this.init(); } Download.prototype.init = function() { var self = this; $(this.element).click(function() {//绑定目标元素,实现iframe懒加载 if (self.beforeDownload() === false) { return false; } if ($('#iframeForDownload').length != 0) {//复用第一次创建的iframe var url = self.getUrl(); $('#iframeForDownload').attr('src',url + self.makeQueryStr()); return false; } var _iframe = self.createIframe(); $(document.body).append(_iframe); return false;//返回false,以防触发a标签的默认行为 }) } Download.prototype.beforeDownload= function() {//该函数返回false代码不能进行下载 if (this._beforeDownload && this.isFunction(this._beforeDownload) && this._beforeDownload() === false) { return false; } else { return true; } } Download.prototype.createIframe = function() {//创建iframe var _iframe = document.createElement('iframe'); _iframe.id = 'iframeForDownload'; _iframe.src = this.getUrl() + this.makeQueryStr(); _iframe.style.display = 'none'; _iframe.callback = this.callback.bind(this); return _iframe; } Download.prototype.getUrl = function() {//获取url return this.isFunction(this.url) ? this.url() : this.url; } Download.prototype.isFunction = function(variable) {//判断变量是否为函数 return Object.prototype.toString.call(variable) === '[object Function]'; } Download.prototype.callback = function(ret) { this.isFunction(this._callback) && this._callback(ret); } Download.prototype.makeQueryStr = function() {//格式化查询条件字符串 if (!this.condition) { return ''; } var self = this; var condition = this.condition; var result = []; var keys = Object.keys(condition); $(keys).each(function(index,key) { var value = self.isFunction(condition[key]) ? condition[key].call(self,key) : condition[key].val(); result.push(key+'='+value); }) return "?" + result.join('&'); }
myiframe.html
<!doctype html> <html> <head> <script src="jq16.js"></script> </head> <body> <a href="javascript:void 0;" id="download">download</a> <button type="button" id='btn'>click</button> <input type="text" id="test"> <script type="text/javascript" src="download.js"></script> <script type="text/javascript"> //document.domain = 'xxx.yyy';不同源时需要目标页面和iframe有相同的domain new Download({ url: 'https://localhost/download.php', element: '#btn', callback: function(ret) { console.log(ret) }, beforeDownload: function() { return true; }, condition: { name: function(){return Math.random()}, str: $("#test") } }) </script> </body> </html>
download.php
<?php /* 下载成功 $filename = "test.jpg"; header('Content-Type:image/gif'); header('Content-Disposition: attachment; filename="'.$filename.'"'); header('Content-Length:'.filesize($filename)); readfile($filename); */ //下载出错,document.domain = 'xxx.yyy;不同源时需要目标页面和iframe有相同的domain echo '<script>frameElement.callback({code:-1,msg:"sss"})</script>'; ?>