123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- 'use strict';
- /**
- * 下载图片的模块
- * @version 1.1.0
- * @author xfl <541151284@qq.com>
- */
- class Downloader{
- Downloader = Downloader;
-
- /**
- * 开始下载图片
- * @public
- * @param {String} url 图片的url
- * @param {String} [name] 下载后图片的名字
- * @returns {Promise} [err, res]
- * @example
- *
- let promise = downloader.load(url, imgName);
- promise.then(([err, res])=>{
- console.log(err, res); // err 和 res 只会有一个存在,另一个为null
- });
- */
- async load(url, name){
- url = url.trim();
-
- name = this.getName(url, name); //重新计算存储的文件名及扩展名
-
- let err, res;
- if( !this.isRemoteUrl(url) ){
- // #ifdef APP-PLUS || MP
- [err, res] = [null, {tempFilePath: url}];
- // #endif
- }else{
- //在web端时,downloadFile的作用只是 确定当前的资源和网络,可能会拿到一些下载失败的信息
- [err, res] = await uni.downloadFile({url: url});
- if(err){ //h5下载图片的跨域在这一步就能知道
- return [err, null];
- }else if(res.statusCode !== 200){ //可能是404
- res.errMsg = "downloadFile:fail";
- return [res, null];
- }
- }
-
- // #ifdef H5
- try{
- //如果这里传入 url,则会在另一个窗口打开图片,而不是下载
- this.webDownloadImg(res.tempFilePath, name);
- }catch(e){
- e.errMsg = e.errMsg || e.message || '';
- return [e, null];
- }
- // #endif
- // #ifdef MP-ALIPAY
- return [{errMsg: 'plat not support download!'}, null]; //在支付宝小程序中,不支持saveImageToPhotosAlbum,需要使用其它的方式实现下载
- // #endif
-
- // #ifdef APP-PLUS || MP
- [err, res] = await uni.saveImageToPhotosAlbum({filePath: res.tempFilePath});
- if( err ){
- return [err, null];
- }
- // #endif
-
- return [null, res];
- }
-
- /**
- * 计算文件名及扩展名
- * @public
- * @param {String} url 一个url, 当没有传入文件名时,可以尝试从这个url中去获取文件名
- * @param {String} [name] 文件名 或 文件名.扩展名
- * @param {String} [ext] 扩展名
- * @returns {String} 文件名.扩展名
- * @example
- *
- * 1. getName('aaa/bbbb.txt');
- * //=> bbbb.txt
- *
- * 2. getName('aaa/bbbb.txt', 'uuuuu');
- * //=> uuuuu.txt
- *
- * 3. getName('aaa/bbbb.txt', 'uuuuu', '.js');
- * //=> uuuuu.js
- *
- * 4. getName('aaa/bbbb.txt', 'uuuuu.kkk', '.js');
- * //=> uuuuu.js
- *
- * 5. getName('aaa/bbbb.txt', 'uuuuu.kkk');
- * //=> uuuuu.kkk
- */
- getName(url, name, ext){
- let arr = url.match(/(([\w\d_\-]+)(\.[\w\d_]+))$/); //默认取地址中的文件名
-
- //取出 url 中的文件名和扩展名
- let defaultName = '__default', defaultExt = '.png';
- if(arr){
- defaultName = arr[1] || defaultName;
- defaultExt = arr[3] || defaultExt;
- }
-
- //取出传入的 name 中的文件名和扩展名
- arr = name.match(/\.[\w\d_]+$/);
- if(arr){
- ext = ext || arr[0];
- name = name.replace(/\.[\w\d_]+$/, ''); //去掉name中的扩展名
- }
-
- ext = ext || defaultExt;
- name = name || defaultName;
-
- return name + ext;
- }
-
-
- /**
- * 是否是远程地址
- * @public
- * @param {String} url 需要判断的url
- * @returns {Boolean}
- */
- isRemoteUrl(url){
- return !!url.match(/^https?:\/\//i);
- }
-
- /**
- * 在web端通过a标签来下载文件
- * 注意,在浏览器中用户可能设置了阻止下载文件,此时代码也会正常执行完成,但其实是没有真正地下载文件的。
- * 如果不存在这样的资源,则默认会下载本网页(html文件)
- * @public
- * @param {String} url 要下载的图片地址
- * @param {String} [name=''] 下载后图片的名字
- */
- webDownloadImg(url, name = ''){ //网页中的图片下载
- const body = document.getElementsByTagName('body')[0];
- const aEle = document.createElement('a');
- aEle.setAttribute('download', name);
- aEle.style.display = 'none';
- aEle.href = url;
- aEle.target = '_blank';
-
- body.appendChild(aEle);
- aEle.dispatchEvent( new MouseEvent('click') ); // 模拟鼠标click点击事件
- document.body.removeChild(aEle);
- }
-
- /**
- * 以单例模式 获取实例对象
- * @static
- * @public
- */
- static getInstance(){
- if(!this.__hasInstance){
- this.__hasInstance = new this();
- }
- return this.__hasInstance;
- }
- }
- export default Downloader.getInstance();
|