Is there an alternative to preprocessorScript for Chrome DevTools extensions?

那年仲夏 提交于 2019-12-05 14:02:30

Use the Chrome Debugging Protocol.

First, use DOMDebugger.setInstrumentationBreakpoint with eventName: "scriptFirstStatement" as a parameter to add a break-point to the first statement of each script.

Second, in the Debugger Domain, there is an event called scriptParsed. Listen to it and if called, use Debugger.setScriptSource to change the source.

Finally, call Debugger.resume each time after you edited a source file with setScriptSource.

Example in semi-pseudo-code:

// Prevent code being executed
cdp.sendCommand("DOMDebugger.setInstrumentationBreakpoint", {
  eventName: "scriptFirstStatement"
});

// Enable Debugger domain to receive its events
cdp.sendCommand("Debugger.enable");

cdp.addListener("message", (event, method, params) => {
  // Script is ready to be edited
  if (method === "Debugger.scriptParsed") {
    cdp.sendCommand("Debugger.setScriptSource", {
      scriptId: params.scriptId,
      scriptSource: `console.log("edited script ${params.url}");`
    }, (err, msg) => {
      // After editing, resume code execution.
      cdg.sendCommand("Debugger.resume");
    });        
  }
});

The implementation above is not ideal. It should probably listen to the breakpoint event, get to the script using the associated event data, edit the script and then resume. Listening to scriptParsed and then resuming the debugger are two things that shouldn't be together, it could create problems. It makes for a simpler example, though.

On HTTP you can use the chrome.webRequest API to redirect requests for JS code to data URLs containing the processed JavaScript code.

However, this won't work for inline script tags. It also won't work on HTTPS, since the data URLs are considered unsafe. And data URLs are can't be longer than 2MB in Chrome, so you won't be able to redirect to large JS files.

If the exact order of execution of each script isn't important you could cancel the script requests and then later send a message with the script content to the page. This would make it work on HTTPS.

To address both issues you could redirect the HTML page itself to a data URL, in order to gain more control. That has a few negative consequences though:

  1. Can't reload page because URL is fixed to data URL
  2. Need to add or update <base> tag to make sure stylesheet/image URLs go to the correct URL
  3. Breaks ajax requests that require cookies/authentication (not sure if this can be fixed)
  4. No support for localStorage on data URLs

Not sure if this works: in order to fix #1 and #4 you could consider setting up an HTML page within your Chrome extension and then using that as the base page instead of a data URL.

Another idea that may or may not work: Use chrome.debugger to modify the source code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!