当前位置:   article > 正文

关于通过chrome扩展拦截浏览器请求方案_chrome插件拦截请求 代码

chrome插件拦截请求 代码

介绍

        关于chrome扩展拦截浏览器中请求数据,目前能找到的有三种方式实现,我都尝试过,下面是我个人的见解,欢迎指正。

           方式一:通过chrome API提供的 webRequest的方法进行 拦截

 优点:后台运行,用户无感知

   缺点:官方出于安全考虑,无法获取到 请求的响应体内容

        方式二:通过chrome扩展在content中 对页面注入js脚本 ,重写XMLHTTPRequest的方式进行监听

优点:能获取到请求的响应体,用户无感知

缺点:获取内容不全面,请求头 响应头 获取不全
        因为大部分请求头都是在XHR处理完之后,由浏览器又新增一部分内容 

        方式三:开启浏览器调试模式 

优点:能获取到全面的内容,包括请求头中的 session 信息

缺点:使用过程中 页面上方会有个 消息提示,,用户体验感不好调试的开启方式 是逐个标签页进行调试模式开启,需要对 tab 的新增进行监听

        注:消息提示,可以在浏览器启动时,加上 '-silent-debugger-extension-api',来取消消息框

 总结:为了获取到最全面的请求内容,且考虑用户体验 ,最后使用了第一种和第二种结合的方式

 方案

第一步 content部分的配置

        原理:content部分的原理是,通过注入inject.js重写 XmlHTTPRequest方法 ,在调用open方法的时候,监听 ‘load’事件获取响应后的 XHR对象,从对象里获取( 响应数据,请求数据),并发送给content,content在将消息发送给background处理;

chrome扩展中manifest.json的配置信息

        注:1.必须用 content.js 获取document注入js的方式,content.js运行是不会影响到 页面中的方法。

        2.run_at 需要在document_start 的时候进行注入并调用,这样当页面刷新时候发送的XHR请求也能拦截到,否则只能拦截到页面渲染之后 触发的请求内容
        3.使用all_frames:true,这样即使页面中存在iframe也能进行注入,并拦截到请求内容

  1. "content_scripts":[
  2. {
  3. "matches":["<all_urls"],
  4. "js":["/content.js"],
  5. "run_at":"document_start",
  6. "all_frames":true
  7. }
  8. ],
  9. "web_accessible_resources":["/inject.js"],

content.js中的代码

注:1.需要使用document.creatElement的方式创建script,content注入的时机是 document_start,此时document找不到任何元素标签,网上 使用的 找到header的方式 无法使用,因为根本找不到;

  1. window.addEventListener("message",function(msg){
  2. console.log(msg);
  3. },false)
  4. // 注入方法
  5. let jsPath = '/inject.js'
  6. var temp = document.createElement('script')
  7. temp.setAttribute('type','text/javascript');
  8. temp.src = chrome.exetension.getURL(jspath);
  9. temp.onload = function(){
  10. this.parentNode.removeChild(this);
  11. }
  12. document.head.apppendChild(temp);

inject.js中的代码

注:inject.js 会在当前页面运行,影响到原有的代码逻辑,如果作为测试辅助工具,建议不要使用 下边三个变量名,改为比较复杂且不易重复的变量名,我在使用过程中发现 变量名 open会影响到 windows.open语法的使用,出现报错

  1. var XHR = XMLHttpRequest.prototype
  2. var open = XHR.open;
  3. var send = XHR.send;
  4. XHR.send = function(postData){
  5. this['hookQuery'] = postData
  6. return send.apply(this,arguments);
  7. }
  8. XHR.open = function(method,url){
  9. this._method = method;
  10. this._url = url;
  11. this.addEventListener("load",function(){
  12. window.postMessage({
  13. ...
  14. },"*")
  15. }
  16. return open.apply(this,arguments)
  17. }

第二步 background的配置

        原理:定义一个全局的map,background中通过webRequest提供的API进行 请求监听,获取到的数据存入map中,然后获取content中的消息之后 根据 tabId  请求方式 路径,去map中匹配,匹配成功之后,将两部分的数据进行组装发送到后台,特别需要注意的是:时机问题,content获取到数据前,此时background就已经获取到请求数据,不会出现匹配不到的问题。

background 监听content 消息

  1. chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){
  2. sendResponse('received');
  3. '''
  4. 获取reqeust,sender中的数据内容,并进行匹配拼装,发送到后台
  5. '''
  6. })

background监听请求信息

  1. chrome.webRequest.onBeforeSendHeaders.addListener(details =>{
  2. '''
  3. 获取到请求数据之后,新增到map中
  4. '''
  5. },{urls:["<all_urls>"]},['requestHeaders'])
  1. chrome.webRequest.onCompleted.addListener(details =>{
  2. '''
  3. 获取到响应数据之后,查找请求信息组装到map中
  4. '''
  5. },{urls:["<all_urls>"]},['requestHeaders'])

 注意事项:

        background中的全局map 匹配成功之后要定时清理,监听到的请求内容进行筛选,是xmlHttpRequest类型的才能存入map,且map 需要定时清理,存的太多,不知道会不会影响 浏览器的性能

总结:

        上述方案,亲测有效,并以投入生产运行,其中 inject的监听方式,content的注入时机采用过很多网上提供的方式,发现存在很多坑,上述代码是目前的最优解,如果有问题欢迎私信我,大家一起探讨。

来 看美女了。。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/427398
推荐阅读
相关标签
  

闽ICP备14008679号