我通过 VSCode 插件 Bito,问chatGPT-4,js如何解析curl?最后顺利帮我实现了一个微信小程序工具!

605 阅读4分钟

一、插件Bito,一个号称不需要openAI key 就能玩chatGPT-4 的男人;

bito介绍.png

1.1 以下是我对它的提问:

20230503214333.png

  • 通过跟它的聊天,我猜它内部一定实现了这个功能,具体怎么实现的,一顿追问下,代码里面的正则引起了我的注意,并且说出了它的思路:“使用了正则表达式 /\r?\n/ 将Curl命令分成了多行,并使用数组的reduce方法将每一行连接起来,形成一个参数数组。然后使用for循环遍历数组,将其中的参数取出并赋值到对应的变量中”,跟着这个思路,我自己实现一个其实也不难,说干就干;

二、什么是 curl ?干嘛用的?

-2.1 来看 阮一峰 大佬怎么说的 curl 的用法指南 :curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。curl文档

三、好像在哪里见到过?有种似曾相识的感觉?

  • 3.1 浏览器复制完整urlpostMan的时候,最好的方式就是通过curlimage.png
  • 3.2 复制出来的内容
curl 'https://mcs.snssdk.com/list' \
  -H 'authority: mcs.snssdk.com' \
  -H 'accept: */*' \
  -H 'accept-language: zh-CN,zh;q=0.9' \
  -H 'content-type: application/json; charset=UTF-8' \
  -H 'origin: https://juejin.cn' \
  -H 'referer: https://juejin.cn/' \
  -H 'sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "Windows"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: cross-site' \
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' \
  --data-raw '[{"events":[{"event":"ad_web_block_show","params":"{\"_staging_flag\":0,\"ad_position\":\"creatorhome\",\"ad_url\":\"https://juejin.cn/book/6918979822425210891?utm_source=creator&utm_medium=banner&utm_campaign=xiaoce_LowCode_202304\",\"event_index\":1683096484192}","local_time_ms":1683119960008,"is_bav":1,"ab_sdk_version":"90083871,90081172,90081874","session_id":"5eda070e-4ea9-49f0-be97-303adb6c0134"}],"user":{"user_unique_id":"7078621510457574945","user_id":"3817931570691031","user_is_login":true,"web_id":"7078621510457574945"},"header":{"app_id":2608,"os_name":"windows","os_version":"10","device_model":"Windows NT 10.0","ab_sdk_version":"90083871,90081172,90081874","language":"zh-CN","platform":"Web","sdk_version":"4.2.9","sdk_lib":"js","timezone":8,"tz_offset":-28800,"resolution":"1920x1080","browser":"Chrome","browser_version":"112.0.0.0","referrer":"https://juejin.cn/notification/digg","referrer_host":"juejin.cn","width":1920,"height":1080,"screen_width":1920,"screen_height":1080,"utm_source":"juejingwdhl","custom":"{\"student_verify_status\":\"not_student\",\"user_level\":3,\"profile_id\":\"3817931570691031\"}"},"local_time":1683119960}]' \
  --compressed
  • 3.3 这啥呀?认都不认识,怎么解析? 别慌,既然有这个东西,一定有他的规律,仔细看,第一行的 curl 'https://mcs.snssdk.com/list' \ 是不是我们的目标地址,后面以 -H 开头的参数直接指定标头,那-data-raw又是个啥?通过查阅 curl文档 了解到:“要发送一个以@符号开头的POST正文,为了避免curl试图将其作为文件名加载,请改用--data raw。”

image.png

  • 3.4 来看postman解析出来的结果,从中得到几个重要信息,url、header和请求方式post,这些信息不久已经展示在curl中了嘛,我们只需要用正则匹配出来就行! postman使用curl.png

image.png

四、js解析过程

  • 4.1 这里的写法并不是很完善,但基本可以提取大部分curl,有问题的地方还请各位大佬指点;
let { detail: { value } } = e;
    let curlCmd = value;
    let { urlForm } = this.data;
    // 1.以换行空格,切割成一个数组
    let lines = curlCmd.split(/\r?\n/);
    // 2.匹配单引号中间关键信息
    let regex = /'~?.+'/g;
    // let method = "";
    let headers = [];
    // let data = "";
    let url = "";
    // 3.数组的每一项内容都是独立的
    lines.map((line) => {
      if (regex.test(line)) {
        // 4.去除将单引号,避免干扰后续的提取
        let line_str = line.match(regex)[0].replace(/\'/g, "");
        let headerStr = line_str.split(":", 2);
        // 5.带curl的为http 内容;
        if (line.indexOf("curl") !== -1) {
          url = line_str;
        } else if (line.indexOf("data-raw") !== -1) {
          // 6.带data-raw 暂且设置为post请求方式,其他请求方式一样的提取方式
          urlForm.body = line_str;
          this.setData({
            requestValue: "POST",
            urlForm: urlForm,
          });
        } else if (headerStr) {
          // 7.将文本以 : 分隔成2部分作为键值,同时去除多余 ' :
          let headerKey = line_str.match(/~?.+: /g)[0].replace(/\: /g, "");
          let headerValue = line_str.match(/: ?.+/g)[0].replace(/\: /g, "");
          headers.push({
            key: headerKey,
            value: headerValue,
          });
        }
      }
    });
    urlForm.header = headers;
    this.setData({
      requestUrl: url,
      urlForm: urlForm,
    });
  • 4.2 为了可以修改解析结果,我写了个单页面小程序; 同时支持将解析的结果发送请求,并且将请求后的结果内容导出excel;

cuel解析小帮手.gif

五、为什么要解析它?用postMan解析不行嘛?

  • 5.1 借阮一峰 老师说的一句话:“如果熟练的话,完全可以取代 Postman 这一类的图形界面工具”,在强大的图形化工具面前,用的是挺爽,但你有没有想过人家是怎么实现的,chatGPT是怎么实现的,正是chatGPT提出的思路,让我有了自己写一遍的冲动!代码比较简单,有兴趣的小伙伴可以直接扫码体验一下,代码仓库地址github.com/kuishou68/s… 最后谢谢你的观看,别忘了关注、点赞(^_^)。

fc8085160e757c438fced96f07307c1.jpg