前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单的谷歌插件开发记录

简单的谷歌插件开发记录

作者头像
治电小白菜
发布2020-08-25 15:36:23
1.6K0
发布2020-08-25 15:36:23
举报
文章被收录于专栏:技术综合技术综合

工作上遇到一个小问题, 就是桌面软件里有个打开浏览器获取cookie的功能, 这个功能C#里可能就是打开一个webview, 然后通过api获取页面cookie. 但是在网页端就很坑了, 放iframe也不行, 毕竟打开的页面不是可控的, 无法通信, 存在跨域问题.

功能类似上图 实现代码: https://github.com/klren0312/cookies-chrome-plugin/edit/master/README.md

原理

如果非要获取, 只能用浏览器插件或者套个Electron, 当然还是用浏览器插件啦.浏览器插件, 通过右键点击发送, 可以将获取的cookie和ua发送到需要的页面.

首先插件会在每个页面创建一个id为'content-block'的DOM, 然后主页面会通过postMessage, 通知插件获取主页面的tabId, 随后, 进入需要获取cookieua的页面, 右键获取, 然后通过之前缓存的主页面tabId将获取的cookieua发送到content.js, content.jscookieua组成的json写入id为'content-block'的DOM, 主页面通过mutationObserver监听id为'content-block'的DOM的变化, 触发数据获取

实现

1. 谷歌浏览器插件基本结构

前端内容(content.js), 后台处理(utils.js), 插件弹框(popup.js, popup.html), 以及配置文件(manifest.json). 前面三个JS文件名称都是自定义的, 需要在配置文件中配置

2.配置文件

代码语言:javascript
复制
{
  "name": "Cookie与UserAgent获取",
  "description": "辅助抓取网站登陆后有效Cookies和UserAgent",
  "version": "0.0.3",
  "author": "ZZES",
  "homepage_url": "https://github.com/klren0312/cookies-chrome-plugin",
  "permissions": [
    "contextMenus",
    "tabs",
    "cookies",
    "<all_urls>"
  ],
  "icons": {
    "16": "icon-16.png",
    "48": "icon-48.png",
    "128": "icon-128.png"
  },
  "background": {
    "scripts": [
      "utils.js"
    ]
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"],
    "all_frames":true,
    "run_at": "document_start"
  }],
  "browser_action": {
    "default_icon": "icon-16.png",
    "default_title": "Cookie与UserAgent获取",
    "default_popup": "popup.html"
  },
  "manifest_version": 2
}

主要问题解读

1. permissions

权限介绍可以查看: https://developer.chrome.com/extensions/permissions

权限, 需要操作一些浏览器功能, 就需要列出权限, 比如需要在右键菜单使用插件, 就开启contenMenus; 需要获取tab页信息, 就开启tabs; 需要获取浏览器cookie, 就开启cookies;最后是插件的应用域名, 这个如果想在所有域名下运用, 就使用<all_urls>

2.background

后台相关处理脚本, 幕后工作者, 进行一些浏览器相关操作

3.content_scripts

前台相关操作, 比如DOM操作

4.browser_action

就是浏览器插件那块的图标和弹框

3.background代码

代码语言:javascript
复制
let mainPageId = null

// 将当前页面的cookies复制到剪切板
function copyCookies(info, tab) {
  let cookies = ''
  chrome.cookies.getAll({
    url: tab.url
  }, function (cookie) {
    // 遍历当前域名下cookie, 拼接成字符串
    cookie.forEach(v => {
      cookies += v.name + "=" + v.value + ";"
    })
    // 添加到剪切板
    const input = document.createElement('input')
    input.style.position = 'fixed'
    input.style.opacity = 0
    input.value = cookies
    document.body.appendChild(input)
    input.select()
    document.execCommand('Copy')
    document.body.removeChild(input)
  })
}

// 将当前页面的UA复制到剪切板
function copyUA () {
  const input = document.createElement('input')
  input.style.position = 'fixed'
  input.style.opacity = 0
  input.value = navigator.userAgent
  document.body.appendChild(input)
  input.select()
  document.execCommand('Copy')
  document.body.removeChild(input)
}

// 发送Cookies和UA到主页面
function sendCookieAndUA (info, tab) {
  let cookies = ''
  const ua = navigator.userAgent
  chrome.cookies.getAll({
    url: tab.url
  }, function (cookie) {
    // 遍历当前域名下cookie, 拼接成字符串
    cookie.forEach(v => {
      cookies += v.name + "=" + v.value + ";"
    })
    // 如果存在主页面的 tabId, 则将当前页的cookies发送给主页面
    let sendId = mainPageId ? mainPageId : tab.id
    chrome.tabs.sendMessage(sendId, {
      cookies: cookies,
      ua: ua
    }, function(response) {
      console.log(response)
    })
  })
}

// 给popup使用的方法
// 获取页面ID
function popupGetTabId () {
  return mainPageId
}
// 清除页面ID
function popupCleanTabId () {
  mainPageId = null
}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    // https://zhuanlan.zhihu.com/p/57820028
    if (request !== 'ok') {
      if (request.type === 'tab') {
        if (request.level === 'main') { // 如果页面是主页面, 则将其 tabId 缓存, 并发送给主页面
          mainPageId = sender.tab.id
          sendResponse({type: 'tab', level: 'main', tabId: sender.tab.id})
        }
      } else if (request.type === 'cookies') {
        let cookies = ''
        chrome.cookies.getAll({
          url: request.target
        }, function (cookie) {
          // 遍历当前域名下cookie, 拼接成字符串
          cookie.forEach(v => {
            cookies += v.name + "=" + v.value + ";"
          })
          sendResponse({type: 'cookies', cookies: cookies})
        })
      }

    }
  }
)

var parent = chrome.contextMenus.create({
  "title": "Cookie与UserAgent获取",
  "contexts": ["page"]
})
var copyCookie = chrome.contextMenus.create({
  "title": "提取Cookies至剪切板",
  "parentId": parent,
  "contexts": ["page"],
  "onclick": copyCookies
})

var copyUA = chrome.contextMenus.create({
  "title": "提取UserAgent至剪切板",
  "parentId": parent,
  "contexts": ["page"],
  "onclick": copyUA
})

var sendCookieAndUA = chrome.contextMenus.create({
  "title": "发送Cookies和UA到主页面",
  "parentId": parent,
  "contexts": ["page"],
  "onclick": sendCookieAndUA
})

4.content代码

代码语言:javascript
复制
(function() {
    document.addEventListener('DOMContentLoaded', function () {
        var div = document.createElement('div')
        div.id = 'cookie-block'
        div.style.display = 'none'
        document.body.appendChild(div);
    })
    chrome.runtime.onMessage.addListener(
        function (request, sender, sendResponse) {
            if (request !== 'ok') {
                document.getElementById('cookie-block').innerText = JSON.stringify(request)
                sendResponse('ok')
            }
        }
    )
})();
window.addEventListener('message', event => {
    if (event.source !== window) {
        return
    }
    // 如果是主页面发送message, 则与background通信, 获取页面的 tabId
    if (event.data && event.data.hasOwnProperty('type') && event.data.type === 'tab' && event.data.hasOwnProperty('level') && event.data.level === 'main') {
        chrome.runtime.sendMessage({type: 'tab', level: 'main'}, function(response) {
      console.log('收到响应', response)
    })
    }
}, false)

5.功能演示

1.右键复制当前页Cookies

演示图片

1.gif

2.右键复制当前页UserAgent

演示图片

2.gif

3.右键将Cookies和UserAgent发送到主页面 主页面需要先发送 message 给插件, 缓存页面 tabId

代码语言:javascript
复制
window.parent.postMessage({type: 'tab', level: 'main'}, '*');

然后在要获取Cookie与UserAgent的页面右键选择"发送Cookies和UA到主页面"

演示图片

3.gif

6.参考资料

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原理
  • 实现
    • 1. 谷歌浏览器插件基本结构
      • 2.配置文件
        • 主要问题解读
        • 3.background代码
      • 4.content代码
        • 5.功能演示
          • 6.参考资料
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档