Write "Google extension" convenient "self-test" to check whether the information reported by the buried point is correct

Write "Google extension" convenient "self-test" to check whether the information reported by the buried point is correct

Recommend the Google extension getting started &svelte article I wrote earlier:

Remember a simple and easy to understand practical sharing meeting of front-end "chrome extension" (Part I)
Record a front-end "chrome plug-in" basic actual combat sharing meeting (recommended Collection) (Part 2)
Talk about Svelte.js technology, what it does and how to implement it (Part 1)
Talk about Svelte.js technology, what it does and how to implement it (Part 2)

background

Every time the embedded point function of the project is developed, the embedded point self-test needs to be carried out. At this time, I can only filter on the Network of the console. Because the request parameter of the embedded point is an "object type", it is necessary to click the transmission parameters one by one and find the key params, but params is a string serialized by JSON, and JSON.parse(xxxxx.params) needs to be carried out;, Then open the array structure in it. Because multiple buried point information may be reported together, JSON.parse is followed by data. Finally, filter out the ten inherent parameters, and only look at the newly added buried point parameters.

The above process is very regular, so it can be abstracted into a tool search logic. Then we can disassemble the problem into three steps:

  1. (display) there is a suitable interface to display the requested data you want.
  2. (get) intercept the request you want.
  3. (processing) parse the requested parameters according to fixed rules, and eliminate the parameters and parents that do not need to be viewed.
  4. (configuration) you can configure which requests need to be monitored.

Of course, it's not just the function of embedding points. You can do similar plug-ins as long as you have the need to analyze api data.

Final effect

I. definition of simulated data

Buried point reporting data I'll show you a general data structure here. You can adjust it according to the business. Suppose the following data structure is the reporting parameter of the buried point reporting api

[
  {
    events: [
      {
        eventName: "Event name: Click event",
        params:
          '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn1", "new2":"nnnnnn2"}',
        xxxxxxxx: 1636179764881,
        xxxxxxx: 0,
      },
      {
        eventName: "Event name: Cancel event",
        params:
          '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn2", "new3":"nnnnnn3"}',
        xxxxxxxx: 1636179764881,
        xxxxxxx: 0,
      },
    ],
    user: {
      userId: 123,
      userName: "lulu",
    },
    header: {
      app_id: 999,
      os_name: "mac",
      os_version: "10_15_7",
      device_model: "Macintosh",
      language: "zh-CN",
    },
  },
];
  1. The passed parameter itself is an "object type"
  2. The first layer is mainly "buried point event", "user information", "equipment information & more"
  3. "Events" is an array of events
  4. "eventName" is the event name, and "params" is the event parameter serialized by "JSON"
  5. There are some default values we don't need to see in "params", because each buried point will bring some default information such as "path information" & "stay event" & "user operation path", which we don't need to add manually, so we don't need to see its correctness every time.
  6. "new1, new2, new3" are our newly added parameters, that is, the parameters we focus on verification this time

Two. Emit the embed data.

Write two buttons to report the buried point request to facilitate our subsequent verification, and create a new html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button onclick="send(`https://Zhangzhaosong1. COM / `) "> click submit 1 < / button >
    <button onclick="send(`https://Zhangzhaosong2. COM / `) "> click submit 2 < / button >
    <script>
      function send(url) {
        fetch(url, {
          method: "post",
          headers: {
            "Content-Type": "application/json;charset=utf-8;",
          },
          body: JSON.stringify([
            {
              events: [
                {
                  eventName: "Event name: Click event",
                  params:
                    '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn1", "new2":"nnnnnn2"}',
                  xxxxxxxx: 1636179764881,
                  xxxxxxx: 0,
                },
                {
                  eventName: "Event name: Cancel event",
                  params:
                    '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn2", "new3":"nnnnnn3"}',
                  xxxxxxxx: 1636179764881,
                  xxxxxxx: 0,
                },
              ],
              user: {
                userId: 123,
                userName: "lulu",
              },
              header: {
                app_id: 999,
                os_name: "mac",
                os_version: "10_15_7",
                device_model: "Macintosh",
                language: "zh-CN",
              },
            },
          ]),
        }).then(() => {});
      }
    </script>
  </body>
</html>

The main work in the above html is to add two "buttons". Each click sends a post request for simulated reporting of buried points. The reporting of each button is different, so there are two buttons.

3, Create a Google plugin project & define icons

Students who have not seen the basic course must first look at the basic articles, otherwise they can't change their thinking.

Master file

manifest.json

{
  "manifest_version": 2,
  "name": "bury:More convenient observation of buried point data",
  "description": "More convenient observation of buried point data",
  "version": "0.1",
  "browser_action": {
    "default_icon": "images/logo.png"
  }
}

The above icons are free to play, ha

Introducing plug-ins

4, Define console tab

Add in the manifest.json file

{
  "manifest_version": 2,
  "name": "bury:More convenient observation of buried point data",
  "description": "More convenient observation of buried point data",
  "version": "0.1",
  "browser_action": {
    "default_icon": "images/logo.png"
  },
  "devtools_page": "devtools/index.html" // This sentence is new
}

The main function of devtools/index.html is to import js files

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="./index.js"></script>
</body>
</html>

The main function of devtools/index.js is to create tab s

chrome.devtools.panels.create(
  "Buried point verification tab, Restore buried point report information",
  null,
  "../panel/index.html",
  function () {
    console.log("Custom panel created successfully!");
  }
);

The content area style of tab is in panel/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>Created successfully</div>
</body>
</html>

5, Initialize svelte project

The content in the tab is too lazy to operate the dom natively. Using the "react" framework is a little heavy, so this time I chose the "svelte framework". For its specific benefits, please see the article I wrote earlier (the article is placed at the head of the article).

Initial project
npx degit sveltejs/template devpanel

cd ./devpanel

yarn

Let's edit the rollup.config.js file so that the packaged file is directly placed in the panel folder.

  output: {
    sourcemap: false,
    format: "iife",
    name: "app",
    file: production ? "../panel/index.js" : "public/build/bundle.js",
  },

And point the file reference of the index.html file in the panel to our index.js file, and introduce the style < link rel = "stylesheet" href = ". / bundle. CSS" >

The effect of running the command yarn build here is as follows. Please click refresh plug-in and "F12" to reopen the console:

During development, it is at localhost:5000 /. After development, it can be launched together with the plug-in.

6, Intercept request

The core function is to intercept requests. Let's use onRequestFinishedapi

chrome.devtools.network.onRequestFinished.addListener((res) => {})

The data format of the above return value res is as follows:

The key information is available. The request method and url can be used to compare whether it is a request to be intercepted, and the rest of our work is to parse "text".

It should be noted that the value of chrome cannot be read in svelte, so it needs to be wrapped with if (chrome) {}. Therefore, when developing in svelte, I use mock data debugging.

7, Processing data

<script>
  const path = "https://zhangzhaosong.com/";
  import getNowTime from "./getNowTime";

  if (chrome) {
    let checkEvent = "";
    let dataList = [];
    const baseKeyArr = [
      "default1",
      "default2",
      "default3",
      "default4",
      "default5",
      "default6",
      "startTime",
      "endTime",
    ];
    chrome.devtools.network.onRequestFinished.addListener((res) => {
      const req = res.request;
      if (req.method === "POST" && req.url === path) {
        const eventsArr = JSON.parse(req.postData.text);
        eventsArr.forEach((item) => {
          if (item.events) {
            item.events.forEach((event) => {
              const params = JSON.parse(event.params);
              const res = {};
              for (let i in params) {
                if (!baseKeyArr.includes(i)) {
                  res[i] = params[i];
                }
              }
              dataList.unshift({
                res,
                time: getNowTime(),
                eventName: event.eventName,
              });
              dataList = dataList;
            });
          }
        });
        console.log("---", dataList);
      }
    });
  }
</script>

<main>
  <div>list</div>
</main>

<style>
</style>

  1. The baseKeyArr array contains some default keys for embedding points, which are used to filter out values we don't care about
  2. path is the address of the request to be intercepted. Of course, it can also be replaced by regular or the like
  3. getNowTime gets the current time

8, Simple design style

Display the array loop obtained above to form a parameter list of intercepted buried point events:

<main>
  {#each Object.keys(dataList) as item}
    <div>
      <header>
        <span>{dataList[item].time} : </span>
        <span class="title">{dataList[item].eventName}</span>
      </header>
      <ul>
        {#each Object.keys(dataList[item].res) as key}
          <li>
            <span>{key} :</span>
            <span>{dataList[item].res[key]}</span>
          </li>
        {/each}
      </ul>
    </div>
  {/each}
</main>

<style>
  .title {
    background-color: bisque;
  }
</style>

9, Filtering function and clearing function

For ease of use, we can add a filtering function and a clearing function to make it more comfortable to view:

end

The website is exploding. This is it this time. I hope to make progress with you.

Tags: Javascript Front-end React Vue.js

Posted on Sun, 07 Nov 2021 01:01:55 -0500 by Reviresco