• cdp协议简介


    啥是cdp

    根据官网的说法,cdp(Chrome DevTools Protocol) 允许我们检测,调试Chromium, Chrome 和其他基于 Blink的 浏览器. 这个协议被广泛使用. 其中最著名的是 Chrome DevTools,协议的api也由这个团队维护。

    使用cdp的姿势

    如果在浏览器中,当你打开devtools时,其实你已经在使用cdp了,只是感知不深罢了,一种办法可以更直观的感知cdp,就是打开devtools的devtools,具体操作如下:

    1. 将开发者工具设置为独立窗口,dock side点第一个
    2. 在开发者工具上再使用快捷键ctrl+shift+i,就可以打开开发者工具的开发者工具了,现在在新打开的开发者工具的console里面,输入下面的代码:
    let Main = await import('./main/main.js');
    Main.MainImpl.sendOverProtocol('Runtime.evaluate', {expression: 'alert (12345)'});
    

    这时网页会alert 12345,你会发现平时在控制台简单的代码执行,其实是通过cdp远程调用网页的js引擎去执行再返回结果的。

    除此之外,protocol monitor也可以帮助我们更直观的理解cdp。

    几个重要的URL

    当一个页面暴露出它的remote debugging port时,我们就可以借助cdp来对这个网页进行remote debugging了。由于cdp是借助websocket实现的,所以,在一切开始之前,有两个url是比较重要的
    http://localhost:[port]/json/list
    http://localhost:[port]/json/version
    这两个url,可以让我们拿到网页的websocket url,json/list返回的数据类似于:

    [
    {
    description: "",
    devtoolsFrontendUrl: "/devtools/inspector.html?ws=localhost:8080/devtools/page/a31c4d5c-b0df-48e8-8dcc-7c98964e2ebe",
    id: "a31c4d5c-b0df-48e8-8dcc-7c98964e2ebe",
    title: "",
    type: "page",
    url: "xxx://xxx",
    webSocketDebuggerUrl: "ws://localhost:8080/devtools/page/a31c4d5c-b0df-48e8-8dcc-7c98964e2ebe"
    }
    ]
    

    其中webSocketDebuggerUrl就是我们需要的打开remote debugging 的钥匙

    重头戏websocket

    接下来我们连上ws,就可以愉快的远程操作页面了,正如chrome devtools所做的那样,下面是一个例子:

    const WebSocket = require('ws');
    const puppeteer = require('puppeteer');
    
    (async () => {
      // Puppeteer launches browser with a --remote-debugging-port=0 flag,
      // parses Remote Debugging URL from Chromium's STDOUT and exposes
      // it as |browser.wsEndpoint()|.
      const browser = await puppeteer.launch();
    
      // Create a websocket to issue CDP commands.
      const ws = new WebSocket(browser.wsEndpoint(), {perMessageDeflate: false});
      await new Promise(resolve => ws.once('open', resolve));
      console.log('connected!');
    
      ws.on('message', msg => console.log(msg));
    
      console.log('Sending Target.setDiscoverTargets');
      ws.send(JSON.stringify({
        id: 1,
        method: 'Target.setDiscoverTargets',
        params: {
          discover: true
        },
      }));
    })();
    

    更多例子可以在这里

    jsonRPC

    如上面例子所示,当ws连接后,一个发给浏览器的指令大概包括3部分id,method,params,比如一个执行一段console.log('hello')代码的指令:

    {
      "id": 235,
      "method": "Runtime.evaluate",
      "params": {
        "expression": "console.log('hello');",
        "objectGroup": "console",
        "includeCommandLineAPI": true,
        "silent": false,
        "contextId": 1,
        "returnByValue": false,
        "generatePreview": true,
        "userGesture": true,
        "awaitPromise": false
      }
    }
    
    

    chrome devtools可以完成的功能非常庞大,而这些功能基本都是使用这样的一个个指令实现的,让人想起那句古老的中国名言:九层之台,起于垒土。本文完

    参考资料:
    https://chromedevtools.github.io/devtools-protocol
    https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md

  • 相关阅读:
    鼠标拖拽UserChromeJS脚本在线生成器
    Firefox书签转按钮UserChromeJS脚本在线生成器
    [原创]Firefox扩展
    F5和CTRL+F5的区别
    玩转log4j
    xml文件报错之Invalid byte 1 of 1byte UTF8 sequence.
    javascript 事件
    jdbc封装类(连接参数配置与web.xml)
    浅谈DHTML
    基于servlet+smartUpload的文件上传
  • 原文地址:https://www.cnblogs.com/imgss/p/12852595.html
Copyright © 2020-2023  润新知