searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Chrome浏览器插件开发概要-给每个请求增加一个请求头

2024-07-24 09:43:44
383
0

最简单的浏览器插件,包括manifest.json、background.js两个文件,跟页面交互则需要content-script.js,给用户展示一个页面,则需要popup.html。本文的目标是开发一个浏览器插件来实现对请求头的修改。

一、manifest.json

首先,需要使用manifest.json来做一个元数据的录入和文件引入等操作:

{
  "name": "header增加器",
  "version": "1.0.1",
  "manifest_version": 3,
  "description": "header增加器",
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"],
      "run_at": "document_start"
    }
  ],
  "permissions": [
    "declarativeNetRequest",
    "declarativeNetRequestWithHostAccess",
    "declarativeNetRequestFeedback",
    "storage"
  ],
  "host_permissions": ["*://*/*"]
}

此处,Chrome插件的manifest.json文件定义了插件的基本信息、背景脚本、内容脚本、权限以及宿主权限。下面是对这个文件的详细讲解:

基本信息

  • name: 插件的名称,这里是“header增加器”。
  • version: 插件的版本号,这里是1.0.1
  • manifest_version: 清单文件的版本号,Chrome扩展使用版本号来控制API的向后兼容性。这里使用的是3,表示该扩展使用了Chrome扩展平台的一些较新功能。
  • description: 插件的简短描述,这里简单重复了插件的名称。

背景脚本

  • background: 指定了扩展的背景脚本,它是扩展的持久性、全局性的脚本。在这个例子中,它指向了一个名为background.js的Service Worker文件。背景脚本可以在扩展的生命周期内持续运行,并且可以监听来自Chrome浏览器的事件,执行长时间运行的任务等。

内容脚本

  • content_scripts: 定义了一个或多个内容脚本的数组,内容脚本会在匹配的页面内注入并执行。
    • matches: 指定了内容脚本将注入的页面URL模式。这里的"<all_urls>"表示内容脚本会注入到所有打开的网页中。
    • js: 指定了内容脚本的JavaScript文件列表。这里只有一个文件content-script.js
    • run_at: 指定了内容脚本注入页面的时机。document_start表示在文档开始解析时立即注入脚本,这允许脚本在DOM构建之前运行,可以修改或阻止某些元素的加载。

权限

  • permissions: 指定了扩展需要的权限列表。这些权限允许扩展执行某些操作或访问某些资源。
    • declarativeNetRequest 和 declarativeNetRequestWithHostAccess: 允许扩展使用声明式网络请求API,该API允许扩展以声明方式控制网络请求,如修改请求头、重定向请求等。declarativeNetRequestWithHostAccess提供了更高级的功能,允许扩展指定哪些宿主可以访问哪些网络请求。
    • declarativeNetRequestFeedback: 允许扩展收集用户对声明式网络请求规则的反馈。
    • storage: 允许扩展访问浏览器的存储API,如localStorage、sessionStorage等。

宿主权限

  • host_permissions: 指定了扩展可以访问的URL模式。这里的"*://*/*"表示扩展可以访问所有URL。这是为了确保扩展能够对其内容脚本注入的页面进行必要的操作。

总结来说,这个Chrome插件的manifest.json文件定义了一个名为“header增加器”的扩展,它通过内容脚本在所有页面上注入content-script.js,并使用背景脚本(background.js)来执行一些全局性任务。扩展具有修改网络请求、收集用户反馈和访问浏览器存储的权限,并且可以访问所有URL。

 

二、background.js

function parseStringToObject(str) {
    const result = []
    const pairs = str.split(';');  
    pairs.forEach(pair => {  
        const obj = {};  
        const [key, value] = pair.split(':');   
        obj["header"] = key;  
        obj["operation"] = "set";  
        obj["value"] = value;  
        result.push(obj);  
    });  
    return result;  
}  

function Init() {

    // var customHeaders = []
    chrome.storage.local.get("customHeaders", (result)=> {
        if (result.customHeaders) {
            console.log(result.customHeaders);
            const customHeaders = parseStringToObject(result.customHeaders)

=            const initialRules = [
            {
                id: 1,
                priority: 1,
                action: {
                    type: "modifyHeaders",
                    requestHeaders: customHeaders
                },
                condition: {
                    // resourceTypes: ["main_frame", "xmlhttprequest"]
                    excludedResourceTypes: ["ping"]
                }
            },
            ];
        
            chrome.declarativeNetRequest.getDynamicRules(function (res) {
            let rules = res.map((e) => e.id);
            chrome.declarativeNetRequest.updateDynamicRules(
                {
                addRules: initialRules,
                removeRuleIds: rules,
                },
                function (callback) {}
            );
            });
        }
    })
}

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    Init();
});

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action == "modifyHeaders") {
    chrome.storage.local.set({
        customHeaders: request.customHeaders
    }, function() {
        console.log('数据已存储');
    });
    Init()
}
return true;
});

在这个文件中,我们定义了这个插件的后台工作,使用2个linstener来监听事件来触发Init(),在Init()中,我们通过从localStorage中获取指定的字段,拿到这个定义好结构的字段进行解析插入chrome.declarativeNetRequest中,进而改变请求头。

 

三、content-script.js

window.addEventListener("message", (event) => {
  if (event.data.code == "mhv3-customHeaders") {
    var customHeaders = localStorage.getItem("customHeaders");
    chrome.runtime.sendMessage(
      {
        action: "modifyHeaders",
        customHeaders: customHeaders
      },
      (res) => {
        console.log(res)
      }
    );
  }
});

这个文件中我们定义了插件和用户页面内容之间的交互,从而响应用户的操作,本示例中,content-script.js接收一个window的event,在指定的event类型中,向background.js中sendMessage,从而形成前后端的通信。

 

四、使用

将以上三个文件放到一个文件夹,浏览器插件页面打开开发者模式,加载已经解压缩的插件,即可加载此插件,加载插件后,在打开页面中输入内容:

localStorage.setItem('customHeaders', 'Authorization:123456778);
window.postMessage({ cmd: "invoke", code: "mhv3-customHeaders" }, "*");

即可在浏览器的每个请求中加入一个请求头:Authorization: 123456778

0条评论
0 / 1000
王****委
4文章数
0粉丝数
王****委
4 文章 | 0 粉丝
原创

Chrome浏览器插件开发概要-给每个请求增加一个请求头

2024-07-24 09:43:44
383
0

最简单的浏览器插件,包括manifest.json、background.js两个文件,跟页面交互则需要content-script.js,给用户展示一个页面,则需要popup.html。本文的目标是开发一个浏览器插件来实现对请求头的修改。

一、manifest.json

首先,需要使用manifest.json来做一个元数据的录入和文件引入等操作:

{
  "name": "header增加器",
  "version": "1.0.1",
  "manifest_version": 3,
  "description": "header增加器",
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"],
      "run_at": "document_start"
    }
  ],
  "permissions": [
    "declarativeNetRequest",
    "declarativeNetRequestWithHostAccess",
    "declarativeNetRequestFeedback",
    "storage"
  ],
  "host_permissions": ["*://*/*"]
}

此处,Chrome插件的manifest.json文件定义了插件的基本信息、背景脚本、内容脚本、权限以及宿主权限。下面是对这个文件的详细讲解:

基本信息

  • name: 插件的名称,这里是“header增加器”。
  • version: 插件的版本号,这里是1.0.1
  • manifest_version: 清单文件的版本号,Chrome扩展使用版本号来控制API的向后兼容性。这里使用的是3,表示该扩展使用了Chrome扩展平台的一些较新功能。
  • description: 插件的简短描述,这里简单重复了插件的名称。

背景脚本

  • background: 指定了扩展的背景脚本,它是扩展的持久性、全局性的脚本。在这个例子中,它指向了一个名为background.js的Service Worker文件。背景脚本可以在扩展的生命周期内持续运行,并且可以监听来自Chrome浏览器的事件,执行长时间运行的任务等。

内容脚本

  • content_scripts: 定义了一个或多个内容脚本的数组,内容脚本会在匹配的页面内注入并执行。
    • matches: 指定了内容脚本将注入的页面URL模式。这里的"<all_urls>"表示内容脚本会注入到所有打开的网页中。
    • js: 指定了内容脚本的JavaScript文件列表。这里只有一个文件content-script.js
    • run_at: 指定了内容脚本注入页面的时机。document_start表示在文档开始解析时立即注入脚本,这允许脚本在DOM构建之前运行,可以修改或阻止某些元素的加载。

权限

  • permissions: 指定了扩展需要的权限列表。这些权限允许扩展执行某些操作或访问某些资源。
    • declarativeNetRequest 和 declarativeNetRequestWithHostAccess: 允许扩展使用声明式网络请求API,该API允许扩展以声明方式控制网络请求,如修改请求头、重定向请求等。declarativeNetRequestWithHostAccess提供了更高级的功能,允许扩展指定哪些宿主可以访问哪些网络请求。
    • declarativeNetRequestFeedback: 允许扩展收集用户对声明式网络请求规则的反馈。
    • storage: 允许扩展访问浏览器的存储API,如localStorage、sessionStorage等。

宿主权限

  • host_permissions: 指定了扩展可以访问的URL模式。这里的"*://*/*"表示扩展可以访问所有URL。这是为了确保扩展能够对其内容脚本注入的页面进行必要的操作。

总结来说,这个Chrome插件的manifest.json文件定义了一个名为“header增加器”的扩展,它通过内容脚本在所有页面上注入content-script.js,并使用背景脚本(background.js)来执行一些全局性任务。扩展具有修改网络请求、收集用户反馈和访问浏览器存储的权限,并且可以访问所有URL。

 

二、background.js

function parseStringToObject(str) {
    const result = []
    const pairs = str.split(';');  
    pairs.forEach(pair => {  
        const obj = {};  
        const [key, value] = pair.split(':');   
        obj["header"] = key;  
        obj["operation"] = "set";  
        obj["value"] = value;  
        result.push(obj);  
    });  
    return result;  
}  

function Init() {

    // var customHeaders = []
    chrome.storage.local.get("customHeaders", (result)=> {
        if (result.customHeaders) {
            console.log(result.customHeaders);
            const customHeaders = parseStringToObject(result.customHeaders)

=            const initialRules = [
            {
                id: 1,
                priority: 1,
                action: {
                    type: "modifyHeaders",
                    requestHeaders: customHeaders
                },
                condition: {
                    // resourceTypes: ["main_frame", "xmlhttprequest"]
                    excludedResourceTypes: ["ping"]
                }
            },
            ];
        
            chrome.declarativeNetRequest.getDynamicRules(function (res) {
            let rules = res.map((e) => e.id);
            chrome.declarativeNetRequest.updateDynamicRules(
                {
                addRules: initialRules,
                removeRuleIds: rules,
                },
                function (callback) {}
            );
            });
        }
    })
}

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    Init();
});

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action == "modifyHeaders") {
    chrome.storage.local.set({
        customHeaders: request.customHeaders
    }, function() {
        console.log('数据已存储');
    });
    Init()
}
return true;
});

在这个文件中,我们定义了这个插件的后台工作,使用2个linstener来监听事件来触发Init(),在Init()中,我们通过从localStorage中获取指定的字段,拿到这个定义好结构的字段进行解析插入chrome.declarativeNetRequest中,进而改变请求头。

 

三、content-script.js

window.addEventListener("message", (event) => {
  if (event.data.code == "mhv3-customHeaders") {
    var customHeaders = localStorage.getItem("customHeaders");
    chrome.runtime.sendMessage(
      {
        action: "modifyHeaders",
        customHeaders: customHeaders
      },
      (res) => {
        console.log(res)
      }
    );
  }
});

这个文件中我们定义了插件和用户页面内容之间的交互,从而响应用户的操作,本示例中,content-script.js接收一个window的event,在指定的event类型中,向background.js中sendMessage,从而形成前后端的通信。

 

四、使用

将以上三个文件放到一个文件夹,浏览器插件页面打开开发者模式,加载已经解压缩的插件,即可加载此插件,加载插件后,在打开页面中输入内容:

localStorage.setItem('customHeaders', 'Authorization:123456778);
window.postMessage({ cmd: "invoke", code: "mhv3-customHeaders" }, "*");

即可在浏览器的每个请求中加入一个请求头:Authorization: 123456778

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0