跳转至

开源阅读源 JS 说明

预计阅读时长 : 3 分钟

Legado 使用 Kotlin 语言开发,并内置 Rhino JavaScript 引擎,因此可以使用 JavaScript 脚本大幅增加各个规则配置的功能。除了使用 JavaScript 语法,脚本中还可以调用 Kotlin 支持的 Java 方法。

除了 JavaScript 的原生语法,Legado 中自定义的 JS 方法详见 JavaScript 说明 ⧉

语法要求

  • 可以在 <js></js> 中 和 @js: 后使用,规则结果存在 result 中
  • @js: 只能放在其他规则的最后使用,或者在 {{}} 中内置使用
  • <js></js> 可以在任意位置使用,还能作为其他规则的分隔符,例:tag.li<js>...</js>//a
  • result 的值不需要显式返回,会直接把最后一个变量值的值传递给 result

变量使用

字符串变量

  • key : 关键字标识,通常形态为 {{key}}
  • key为关键字标识,通常形态为{{key}},运行时会替换为搜索关键字
  • 也可以对key进行加密等操作,如:{{java.base64Encode(key)}}
  • page : 关键字标识,通常形态为 {{page}}
  • page 的初值为 1
  • 也可以对 page进行计算,如:{{(page-1)*20}}
  • 有时会遇到第一页没有页数的情况,有两种方法:
    • {{page - 1 == 0 ? "": page}}
    • <,{{page}}>
  • baseUrl : 当前 url
  • result : 上一步的结果,在组合规则中代表的上一步规则的结果,独立使用则代表当前 baseUrl 的响应内容
  • title : 当前标题,title
  • nextChapterUrl : 下一章节 url
  • src : 内容,源码

类变量

put 与 get

java.put 与 java.get 只能用于 JavaScript 语法规则中,实现变量的传递。

java.get(key) // 获取变量值
java.put(key, value) // 设置变量,并返回变量值
java.get 的另外用法

根据传递的参数不同,java.get 还可以用作网络请求,具体用法如下:

java.get(url: String, headerMap: Map<String, String>): Connection.Response

在 JavaScript 以外的语法规则中,可以使用 @get 和 @put,注意变量的赋值需要加引号:

@put:{bid:"//*[@bid-data]/@bid-data"}

{{}}

{{}} 可以看做 \${}`` 的语法糖,用于在字符串中调用变量

  • 在搜索 URL 与发现 URL 中的 {{}} 里调用变量时,只能使用 JavaScript,不需要 @js: 开头
  • 在搜索 URL 与发现 URL 以外的 {{}} 里调用变量时,默认使用 JavaScript,不需要 @js: 开头,使用 JSONPath 需要以 @json:$. 开头,CSS 需要以 @css: 开头

通过以上的语法,可以和不同的提取规则配合使用,更加灵活的用在需要使用字符串组合的场景中:

章节信息
1
2
3
4
🕰  更新时间
{{@css:meta[property$=update_time]@content##T.*}}
📜  内容简介
{{@css:.intro_info@text}}##(^|[。!?……;]+[”」)】]?)##$1<br>

常用方法

JSON.stringify()方法

JSON.stringify() 是 JavaScript 最常用的方法之一,它的作用是将一个JavaScript对象转换成一个JSON字符串,这在需要将对象作为字符串传输(例如,通过HTTP请求)时非常有用。

转换后的字符串可以被服务器解析并用来处理请求,根据user-agent、accept-language等信息提供定制化的响应。

@css:a@href@js:result+','+JSON.stringify({"webView": true});

示例代码

搜索地址
1
2
3
4
5
6
7
8
@js:
burl=source.getKey();   //获取书源地址
url = burl+"/e/search/index.php,"+JSON.stringify({
    "method":"POST",
    "charset": "GB2312",
    "body":"keyboard="+key+"&show=title&classid=0"
    });  //拼接搜索地址
result=String(java.connect(url).raw().request().url()).replace('?','<?,index.php?page={{page-1}}&>')
解析内容
var javaImport = new JavaImporter();
javaImport.importPackage(
  Packages.java.lang,
  Packages.javax.crypto.spec,
  Packages.javax.crypto,
  Packages.java.util
);
with(javaImport) {
  function decode(k,i,d) {
    $=(str)=>{
      return java.base64DecodeToByteArray(str)}
    var key = SecretKeySpec($(k), "AES");
    var iv = IvParameterSpec($(i));
    var chipher = Cipher.getInstance("AES/CTR/NOPadding");
    chipher.init(2, key, iv);
    return String(chipher.doFinal($(d)));
  }
}
a=String(result.match(/window.a='([^']+)'/)[1]);
b=String(result.match(/window.b='([^']+)'/)[1]);
c=String(result.match(/window.c='([^']+)'/)[1]);
cookies="haha="+encodeURIComponent(decode(a,b,c))
错误处理
// 显示 js 的报错处理
(function(result){
    try{
          // 处理result
          // ...
          // 当返回结果为字符串时
          return result;
          // 当返回结果为列表时
          return list;
    }
    catch(e){
          // 当返回结果为字符串时
          return ""+e;
          // 当返回结果为列表时
          return [""+e];  //列表对应名称处填""+result查看
    }
})(result);