背景介绍
背景还是有必要介绍一下的。
因为百度云已经把小电影封杀的都成了8秒教育片,115的会员费高的离谱,于是它们的替代品hei科li线云
就急需出现了。
为了下载百度云的普通文件,有一个专门为了推送百度云的下载链接到Aria2的Chrome扩展BaiduExporter,还有针对115的Chrome扩展115exporter。
根据他们的思路,扩展是可以解决以前那种纯手工的复制粘贴办法的,于是研究了一下他们的代码。
- 首先是找到下载的链接,这个功能以前已经实现了。
- 然后是把找到的链接推送到Aira2服务器(当然,首先肯定要自己先建好Aira2服务器,最好外网可以访问的那种)
其中Aira2服务器可以参考Aria2英文官网,不管你是把Aira2安装到哪里,都可以在网上找到对应的教程。
然后通过代码推送链接,我只是研究了一下BaiduExporter项目的相关代码,了解了最基础的用法。
再深一点的功能,我也没有用到,我也不了解。
这些就足够了,于是开始吧。
以下目标网站
都是代表的http://lx点heikeyun点net
以前原始的办法
参考你不知道Aria2的下载速度有多快!
现今的科技自动化
这里可以详细的分析一下怎么把扩展程序无缝结合到目标网站。
目标网站使用的UI是MZUI。
需要注意的是扩展程序是不能直接调用目标网站的JS的,如果有交叉的JS,我的解决办法是把它的代码复制一份,放到自己的扩展程序中。
项目中添加了jquery-3.3.1.min.js
,mzui.js
,toURL.js
,其中前两个是网上下载的,最后一个是解析下载地址需要用到的js。
另外项目主要的功能都放到了myHeike.js
中。
先添加Aira2下载按钮(方法startListen)
主要代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ... this.startListen = function () { this.initHeike(); var target4 = $("#target4"); var btns = target4.find(".content"); var btnmain = $("#btnmain"); var btn = '<button type="button" class="btn success" id="aria2btn"><i class="icon icon-cloud-download" style="margin-right: 6px;"></i>Aria2</button>'; btns.append(btn); $("#aria2btn").attr("style", btnmain.attr('style')); $("#aria2btn").bind('click', (obj) => { this.getDownloadURL(); }); $.messager.show('程序初始化成功!', {type: 'success', placement: 'center'}); } ...
|
根据目标网站的html
代码,添加一个类似的按钮Aria2
,并绑定了点击事件this.getDownloadURL()
。
得到下载链接(方法:getDownloadURL)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| ... this.getDownloadURL = function () { var that = $($(this.dItem.currentTarget)[0]); var obj = this; var data = that.attr('data'); $.ajax({ type: "post", url: "CommonAjax.ashx?type=DownUrl", data: "{'d':'" + data + "','tp':'web'}", dataType: "json", async: true, beforeSend: () => {$.messager.show('正在获取下载地址……', {type: 'info', placement: 'center'});}, success: function (d) { if (d.IsOk) { obj.sendUrl(bcone(d.DownUrl)); } else { $.messager.show(d.Msg, {type: 'danger', placement: 'center'}); return; } }, error: function (err) { $.messager.show(err, {type: 'danger', placement: 'center'});; return; } }); } ...
|
需要注意,代码都封装在一起,里面的this
每次指向的并不是当前的js类。这个就把我弄的头晕了。
当然这个方法是参考的目标网站的js,因为扩展程序都是在网页上运行的,所以设备都确定为'tp': 'web'
。
得到下载地址后,就需要使用方法sendURL方法把链接推送到Aira2服务器。
推送Aira2下载链接(方法:sendUrl)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ... this.sendUrl = function (path) { $.messager.show('已经取得下载地址,正在推送到Aira2服务器', {type: 'success', placement: 'center'}); var rpcData = { jsonrpc : '2.0', id : new Date().getTime(), method : 'aria2.addUri', params : [ [path], { continue : 'true', split : '10', 'max-connection-per-server' : '10', } ] } $.post(this.url, JSON.stringify(rpcData), (res) => { if(res.error == undefined || res.error == null){ $.messager.show('任务添加成功,请返回Aria2查看任务', {type: 'success', placement: 'center'}); } }) } ...
|
这是最基础的发送下载URL到Aria2服务器的方法,其中rpcData
的params
参数,可能加入的字段应该有好多,只是暂时只用了这几个字段而已。
推送方法直接使用$.post方法,把rpcData
转成json格式的数据就可以推送过去了。返回的数据,当出现错误的时候(暂时没有遇到),就不能添加成功。
当然出现错误时的提示功能还需要完善。
到此为止,其实就实现了全部的核心功能。
但是很多时候是不能把Aria2服务器的地址直接写到程序里的,那样可移植性就很差了,需要加入自定义Aria2服务器的界面。
存储自定义字段的值,可以使用浏览器自带的localStorage
,明文存储应该也没多大影响。因为毕竟客户端程序,能实现复杂的加密也不现实。
自定义Aria2服务器的方法
根据需要,选择浏览。
在目标网页的指定页面,左下角加入了一个按钮,默认是隐藏的,点击后可以弹出自定义界面。
自定义界面(方法:initHeike)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| ... this.initHeike = function () { $.messager.show('正在初始化程序……', {type: 'info', placement: 'center'}); var list = $("#partial").find('.list').children(); $.each(list, (i, v) => { $(v).bind('click', (item) => { this.dItem = item; $($('.display-backdrop')[0]).remove(); }); }); var rpcHtml = '<div id="target66" class="" style="width: 340px; background: #FFF; position: absolute; left: 10px; z-index: 6666; display: none;">' + '<div class="heading">' + '<div class="title"><strong>设置Aira服务器</strong></div>' + '</div>' + '<div class="content article box">' + '<div class="control has-label-left has-icon-right">' + 'URL(类似:http://localhost:6800/jsonrpc):<input name="rpcURL" type="text" id="rpcURL" class="input" placeholder="Aria2服务器地址" style="width: 90%; display: block; padding-left: 10px;">' + 'Token(如果没有Token可以留空):<input name="rpcToken" type="text" id="rpcToken" class="input" placeholder="Token" style="width: 50%; display: inline-block; padding-left: 10px; margin-right: 10px">当前状态:<span id="status"></span>' + '<div><input type="button" name="btnCheckRPC" value="测试连接" id="btnCheckRPC" class="btn primary circle" style="margin-top: 10px; margin-right: 10px;">' + '<input type="button" name="btnSaveRPC" value="保存" id="btnSaveRPC" class="btn success outline circle" style="margin-top: 10px;"></div>' + '</div>' + '<div class="control has-label-left has-icon-right"><hr>首次使用本插件,需要设置Aira2服务器。</div>' + '</div>' + '</div>'; var rpcset = '<nav id="fabNav66" class="affix dock-bottom dock-left fab has-padding dock-auto shadow-none" style="margin-left: 70px;">' + '<a id="rpcBtn" class="btn circle primary layer"><i class="icon icon-cog" style="margin-right: 4px;"></i></a>' + '</nav>'; $("#partial").append(rpcset); $('body').append(rpcHtml); $('#rpcURL').val(this.url == null ? '' : this.url); $('#rpcToken').val(this.token == null ? '' : this.token); if(this.rpcStatus == '1'){ setStatus('#status', '已连接', 'green'); }else{ setStatus('#status', '未连接', 'red'); } $('#rpcURL, #rpcToken').blur( () => { if($('#rpcURL').val() != this.url || $('#rpcToken').val() != this.token){ setStatus('#status', '测试连接', 'red'); this.rpcStatus = '0'; } }); $('#btnCheckRPC').click( () => { this.getRPCVersion($('#rpcURL').val(), $('#rpcToken').val()); }); $('#btnSaveRPC').click( () => { localStorage.setItem('url', $('#rpcURL').val()); localStorage.setItem('token', $('#rpcToken').val()); localStorage.setItem('rpcStatus', this.rpcStatus); }); $('#target66').css('top', ($('#fabNav66').offset().top - $('#target66').height() - 10) + 'px'); $('#fabNav66').click( () => { $('#target66').slideToggle(); }); if(this.url != null && this.rpcStatus == '1'){ $('#rpcBtn').append('已连接'); }else{ $('#rpcBtn').append('未连接'); } } ...
|
此段程序可能比较啰嗦,主要是用来控制界面的显示。
填写好Aira2服务器地址后,需要测试Aria2服务器是否可用。这里就需要用到getRPCVersion
方法测试其连通性。
测试Aira2服务器是否可用(方法:getRPCVersion)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| ... this.getRPCVersion = function (aria2Url, aria2Token) { var aria2 = { url : aria2Url, token : aria2Token, } var rpcData = { jsonrpc : '2.0', method : 'aria2.getVersion', id : 1, params : [] } $.post(aria2.url, JSON.stringify(rpcData), (res) => { var ver = ''; if(res != null && res != undefined){ var d = res.result.version; if(d != null && d != undefined){ ver = d; } console.log(res); } if(ver == ''){ setStatus('#status', '连接错误', 'red'); this.rpcStatus = 0; $('#rpcBtn').html($('#rpcBtn').html().replace("已", "未")); } else{ setStatus('#status', '已连接', 'green'); this.rpcStatus = 1; $('#rpcBtn').html($('#rpcBtn').html().replace("未", "已")); } }).fail( () => { setStatus('#status', '连接错误', 'red'); this.rpcStatus = 0; $('#rpcBtn').html($('#rpcBtn').html().replace("已", "未")); }); } ...
|
这个和推送URL方法类似,只是发送的参数有点不一样。
如果Aria2服务器地址没有问题,就会返回Aria2的版本号。
如果连接不成功,可能什么都不返回,连接都不会成功,估计是404。
尾声
我几乎把整个代码都贴上来了。
我就是啰嗦而且找不到重点。
我把代码放到了Github上HeiKeExport。
程序目前是有问题的,我只在两台电脑上测试过,一台是本机,也就是开发这个扩展程序的电脑,扩展测试正常,打包扩展程序HeiKeExport.crx
;另一台安装安装前面打包的扩展程序HeiKeExport.crx
,提示程序出错。
但是把整个代码解压到新电脑以后,新电脑开启开发者模式,加载正在开发的扩展程序,是没有问题的。
于是,我怀疑是新电脑的Chrome版本的问题。