您的位置:新葡亰496net > 新葡亰官网 > 新葡亰496net:Chrome插件开辟计算,手把手教你付

新葡亰496net:Chrome插件开辟计算,手把手教你付

发布时间:2019-12-01 01:18编辑:新葡亰官网浏览(54)

    Chrome 扩展程序的开发与发布 — 手把手教你开发扩展程序

    2017/12/08 · 基础技术 · Chrome, 扩展程序

    本文作者: 伯乐在线 - chokcoco 。未经作者许可,禁止转载!
    欢迎加入伯乐在线 专栏作者。

    关于 chrome 扩展的文章,很久之前也写过一篇。新葡亰496net:Chrome插件开辟计算,手把手教你付出扩大程序。清除页面广告?身为前端,自己做一款简易的chrome扩展吧。

    本篇文章重在分享一些制作扩展的过程中比较重要的知识及难点。

     

    关于 chrome 扩展的文章,很久之前也写过一篇。清除页面广告?身为前端,自己做一款简易的chrome扩展吧。

    架构

    • ### 总括:

      • Manifest:程序清单
      • Background:插件运行环境/主程序
      • 新葡亰496net:Chrome插件开辟计算,手把手教你付出扩大程序。Pop up:弹出页面
      • Content scripts:与浏览页面交互的脚本
    • ### Manifest

      每一个扩展都有一个JSON格式的manifest文件,叫manifest.json,相当于程序清单,其中定义了插件的一些元数据等信息,示例如下:

    {
      // 必须添加
      "manifest_version": 2, //固定的,定义manifest版本信息
      "name": "My Extension", //插件名称
      "version": "1.0", //插件本身的版本
    
      // 推荐添加
      "default_locale": "en",
      "description": "This is my first extension.", //插件的描述
      "icons": {...},
    
      //browser_action和page_action只能添加一个
      "browser_action": { //浏览器级别行为,所有页面均生效
            "default_icon": "cc.gif",//图标的图片
            "default_title": "Hello CC", //鼠标移到图标显示的文字 
            "default_popup": "popup.html" //单击图标后弹窗页面
        }, 
      "page_action":{ //页面级别的行为,只在特定页面下生效 
            "default_icon":{
                "24":"icon_24.png",
                "38":"icon_38.png"
                },
            "default_popup": "popup.html",
            "default_title":"MyTitle"
        },
    
      // 可选
      "author": ...,
      "automation": ...,   
    
      //background script即插件运行的环境
      "background":{
            "page":"background.html", //page和scripts只能设置一个   
            "persistent": false   
    
            //scripts定义一个脚本文件的数组,chrome会在扩展启动时自动创建一个包含所有指定脚本的页面
            // "scripts": ["js/jquery-1.9.1.min.js","js/background.js"]
        },
      "background_page": ...,
      "chrome_settings_overrides": {...},
      "chrome_ui_overrides": {
        "bookmarks_ui": {
          "remove_bookmark_shortcut": true,
          "remove_button": true
        }
      },
      "chrome_url_overrides": {...},
      "commands": {...},
      "content_capabilities": ...,
    
      //定义对页面内容进行操作的脚本
      "content_scripts": [{  
             "matches": ["http://*/*","https://*/*"],//只在这些站点下 content_scripts会运行
             "js": ["js/jquery-1.9.1.min.js", "js/js.js"],   
             "run_at": "document_start",  //在document加载时执行该脚本,如果不指定,则在document加载完成后执行
        }] 
    
      "content_security_policy": "policyString",
      "converted_from_user_script": ...,
      "current_locale": ...,
      "devtools_page": "devtools.html",
      "event_rules": [{...}],
      "externally_connectable": {
        "matches": ["*://*.example.com/*"]
      },
      "file_browser_handlers": [...],
      "file_system_provider_capabilities": {
        "configurable": true,
        "multiple_mounts": true,
        "source": "network"
      },
      "homepage_url": "http://path/to/homepage",
      "import": [{"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}],
      "incognito": "spanning, split, or not_allowed",
      "input_components": ...,
      "key": "publicKey",
      "minimum_chrome_version": "versionString",
      "nacl_modules": [...],
      "oauth2": ...,
      "offline_enabled": true,
      "omnibox": {
        "keyword": "aString"
      },
      "optional_permissions": ["tabs"],
      "options_page": "options.html",
      "options_ui": {
        "chrome_style": true,
        "page": "options.html"
      },
    
      //数组,声明插件所需要的权限
      "permissions": [ 
            "http://*/", 
            "bookmarks", 
            "tabs", 
            "history",
            "activeTab",
            "storage"
        ], 
      "platforms": ...,
      "plugins": [...],
      "requirements": {...},
      "sandbox": [...],
      "short_name": "Short Name",
      "signature": ...,
      "spellcheck": ...,
      "storage": {
        "managed_schema": "schema.json"
      },
      "system_indicator": ...,
      "tts_engine": {...},
      "update_url": "http://path/to/updateInfo.xml",
      "version_name": "aString",
      "web_accessible_resources": [...]
    }
    
    • ### Background Page

      • background是插件的运行环境,姑且叫做主程序。一旦插件被启用,chrome就会为该插件开辟一个独立运行环境,用来执行background script。若设置了scripts字段,浏览器的扩展系统会自动根据scripts字段指定的所有js文件自动生成背景页。也可以直接page字段,指定背景页。两者只能设置一个
      • 一般情况下,我们会让将扩展的主要逻辑都放在 background 中比较便于管理。其它页面可以通过消息传递的机制与 background 进行通讯。理论上 content script 与 popup 之间也可以传递消息,但不建议这么做。
      • 包含background.html和background.js两个文件,包括如下两种:
        • Persistent background pages:一直开启
        • Event pages:需要时开启,可通过将persistent设置为false来设置
          • 开启时机:
            • 首次安装或更新完版本时
            • 触发特定事件时
            • content script 向其发送消息时
            • 其他页面(例如popup)调用runtime.getBackgroundPage
          • 注册到Manifest中:
            {
             "name": "My extension",
             ...
             "background": {
               "scripts": ["eventPage.js"],
               "persistent": false
              },
             ...
             }
    
    • ### UI Page

      • #### popup:

        • popup.html和popup.js:popup和background page在同一个运行环境中,均在插件主程序中。也就是说popup可以通过特定的方式调background里的方法。注:出于安全考虑,javascript必须与html分开存放且写在html里的js无效。
      • #### option:

    • ### Content Scripts

      Content Scripts相当于一个对当前浏览页面(符合matches定义的模式)的补充脚本,称作内容脚本,与popup不同,内容脚本几乎与主程序运行环境相隔离、独立。与主程序的交互只能通过发送消息的方式进行。

      • CanDo:
        可以访问和修改单前浏览页面的DOM,但不能访问该页面脚本定义的变量和方法,并且不会和该页面原有js的方法和变量冲突。
      • CanNot:
        • 不能使用chrome独有API,除了以下几点:
          • extension(getURL,inIncognitoContext,lastError,onRequest,sendRequest)
          • i18n
          • runtime ( connect , getManifest , getURL , id , onConnect , onMessage , sendMessage )
          • storage
        • 不能使用插件里其他页面定义的变量和方法
      • 向访问的页面注入脚本,访问和修改DOM的方式:
        只有为要访问的页面赋予权限才可以,需在Manifest中添加permissions节点。
        向页面插入脚本的API:
      • 注入脚本:chrome.tabs.executeScript,如下:
        //将访问页面的背景变为红色
        chrome.browserAction.onClicked.addListener(function(tab) {
          chrome.tabs.executeScript({
            code: 'document.body.style.backgroundColor="red"'
          });
        });
    
    • 注入CSS:chrome.tabs.insertCSS
    • 注册到Manifest中
        {
          "name": "My extension",
          ...
          "content_scripts": [
            {
              "matches": ["http://www.google.com/*"],//只有在符合该pattern的站点才会运行
              "css": ["mystyles.css"],
              "js": ["jquery.js", "myscript.js"]
            }
          ],
          //为以下页面赋予访问并向注入脚本的权限
          "permissions": [
            "tabs", "http://www.google.com/*",
            "activeTab"
          ],
          ...
        }
    
    • 消息传递:
      虽然内容脚本的执行环境和托管它们的页面是彼此隔离的,但它们共享对页面DOM的访问权限,如果页面希望与内容脚本(或通过内容脚本进行扩展)进行通信,那么它必须通过共享的DOM进行。示例如下:
          //访问的页面:
          document.getElementById("theButton").addEventListener("click",
        function() {
        window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
        }, false);
    
        //content_scripts脚本;
        var port = chrome.runtime.connect();
    
        window.addEventListener("message", function(event) {
        // We only accept messages from ourselves
        if (event.source != window)
          return;
    
        if (event.data.type && (event.data.type == "FROM_PAGE")) {
          console.log("Content script received: "   event.data.text);
          port.postMessage(event.data.text);
          }
        }, false);
    

    什么是 chrome 扩展程序

    扩展程序是一些能够修改或增强 Chrome 浏览器功能的小程序。对于前端工程师而言,其最大的便利就是我们可以应用我们熟悉的 HTML、CSS 、 Javascript 等技术来制作扩展程序。

    如下图所示,这些图标就是各种开发者提供的 chrome 扩展程序:

    新葡亰496net 1

    本篇文章重在分享一些制作扩展的过程中比较重要的知识及难点。

    新葡亰496net 2

    插件页面间通讯:

    插件各个部分之间的通讯有如下两种模式:

    • ### 简单的单次请求

      • 内容脚本到主程序:
    chrome.extension.sendMessage({hello: "Cissy"}, function(response) {
        console.log(response.farewell);
    });
    
    • 主程序到内容脚本
    chrome.tabs.query({active:true}, function(tab) {
        chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
            console.log(response.farewell);
        });
    });
    
    • 接收消息
      chrome.extension.sendMessage()向扩展内的其它监听者发送一条消息。此消息发送后会触发扩展内每个页面的chrome.extension.onMessage()事件。
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
            console.log(sender.tab ?
                "from a content script:"   sender.tab.url :
                "from the extension");
            if (request.greeting == "hello")
                sendResponse({farewell: "goodbye"});
    });
    
    • ### 长连接

      • background 和 popup
        background和popup运行在同一个进程中,都是运行在主程序中的,所以background 和 popup 之间可以直接相互调用对方的方法,不需要消息传递。
        • popup调用background中变量或方法
    var bg = chrome.extension.getBackgroundPage();//获取background页面
    console.log(bg.a);//调用background的变量或方法。
    

    注:

    区分扩展与插件

    很多人会误称扩展程序为插件,这里有必要区分一下。

    “扩展” 和 “插件”,其实都是软件组件的一种形式,Chrome 只不过是把两种类型的组件分别给与了专有名称,一个叫 “扩展”,另一个叫 “插件”。

    • 扩展(Extension)

    指的是通过调用 Chrome 提供的 Chrome API 来扩展浏览器功能的一种组件,工作在浏览器层面,使用 HTML Javascript 语言开发。比如著名的 Adblock plus。

    • 插件(Plug-in)

    指的是通过调用 Webkit 内核 NPAPI 来扩展内核功能的一种组件,工作在内核层面,理论上可以用任何一种生成本地二进制程序的语言开发,比如 C/C 、Delphi 等。比如 Flash player 插件,就属于这种类型。一般在网页中用 <object>或者&lt;embed&gt;标签声明的部分,就要靠插件来渲染。

     

     

    这次的练习是做一个Chrome的扩展,分享一下入门开发过程。因为在消息传递那块纠结了特别久,所以我会重点总结消息传递那块。

    使用chrome.extension.getBackgroundPage()时要确保此时的backgroundpage在运行,否则会返回null,解决方案:

    将manifest的background的persistent属性值设置为true,确保backgroundpage处于常开状态(我使用的该方法);

    "background": {
            "scripts": [
                "background.js"
            ],
            "persistent": true
        }
    
      - 使用异步的 chrome.runtime.getBackgroundPage代替(该方法没测试)
    - background调用popup中变量或方法
      background是一个运行在扩展进程中的HTML页面。它在你的扩展的整个生命周期都存在,而popup是在你点击了图标之后才存在,所以,在获取popup变量时,请确认popup已打开。
    
    var pop = chrome.extension.getViews({type:'popup'});//获取popup页面
    console.log(pop[0].b);//调用第一个popup的变量或方法。
    
    • background 和 content
      持续长时间的保持会话需要在content script和扩展建立一个长时间存在的通道。当建立连接,两端都有一个runtime.Port 对象通过这个连接发送和接收消息。
      • 内容脚本发送消息到扩展程序
    var bac = chrome.extension.connect({name: "ConToBg"});//建立通道,并给通道命名
    bac.postMessage({hello: "Cissy"});//利用通道发送一条消息。
    
    - 扩展程序发送消息到内容脚本
    
    var cab = chrome.tabs.connect(tabId, {name: "BgToCon"});//建立通道,指定tabId,并命名
        cab.postMessage({ hello: "Cissy"});//利用通道发送一条消息。
    
    - 接收消息
    接收消息为了处理正在等待的连接,需要用chrome.extension.onConnect 事件监听器,对于content script或者扩展页面,这个方法都是一样的
    
    chrome.extension.onConnect.addListener(function(bac) {//监听是否连接,bac为Port对象
        bac.onMessage.addListener(function(msg) {//监听是否收到消息,msg为消息对象
            console.log(msg.hello);
        })
    })
    

    开发自己的扩展程序

    OK,简单了解完什么是扩展程序后,下面我们来看看如何开发一款扩展程序。

    当然,首先我们要搞清楚为什么我们需要扩展程序,它有什么作用呢?

    就我而言,最近我开发了一款简单的扩展程序 —— URLHelper 。你可以在 chrome 应用商店下载到它:

    新葡亰496net 3

    开发它的原因是因为,在我们的业务开发中,开发过程经常需要面对超长的 URL,带有 N 多个参数,它可能长这样:

    1
    http://tv.video.qq.com/xxx/xxx/xxx/index?rootdomain=test.tv.video.qq.com&guid=066de07bdd33422f95b7ddaf993b2004&tvid=0930DCE900E081E142ED006B56025BA7&appver=3.1.0&bid=31001&appid=101161688&vipbid=38&fromvipbid=38&cid=qk97pyegxz8kdug&vid=&pid=&mid=&from=501&qua_info=PT=SNMAPP&CHID=10009&VN=3.1.0&PR=VIDEO&TVKPlatform=670603&SMARKET=&type=0&listid=&matchid=&channelid=&source1=747&source2=709&penid=D21D81E4489E43422F842235B52DD&access=82E8E64DDD4A531B6FFA3E0967F76&kt_login=qq&vuserid=&vusession=&oauth_consumer_key=101161688&kt_userid=924400965&kt_license_account=SNM_0059858531&main_login=qq&kt_login_support=qq,wx,ph&kt_boss_channel=tx_snm&ott_flag=2&sop=9&actid=&tvactid=&tv_params=policy_id=88&disable_update=&dp=&du=&viewid=&dv=&pageid=&ptag=&redirect_url=http://test.tv.video.qq.com/ktweb/pay/phone/scan?rootdomain=test.tv.video.qq.com&guid=066de07bdd33422f95b7ddaf993b2004&tvid=0930DCE900E081E142ED006B56025BA7&appver=3.1.0&bid=31001&appid=101161688&vipbid=38&fromvipbid=38&cid=qk97pyegxz8kdug&vid=&pid=&mid=&from=501&qua_info=PT%3DSNMAPP%26CHID%3D10009%26VN%3D3.1.0%26PR%3DVIDEO%26TVKPlatform%3D670603%26SMARKET%3D&type=0&listid=&matchid=&channelid=&source1=747&source2=709&openid=D21D81E44801E9E43422F842235B52DD&access_token=82E8E64DDD4EDA531B6FFA3E09676F76&kt_login=qq&vuserid=&vusession=&oauth_consumer_key=101161688&kt_userid=924400965&kt_license_account=SNM_0059858531&main_login=qq&kt_login_support=qq%2Cwx%2Cph&kt_boss_channel=tx_snm&ott_flag=2&sop=9&actid=&tvactid=&tv_params=policy_id%3D88&disable_update=&dp=&du=&viewid=&dv=&pageid=&ptag=&opres=0&$from=201

    不是开玩笑,真实情况可能比这个还长。新葡亰496net 4

    因为调试的需要,经常要找到某一个特定的参数,获取或者修改它的值。

    读者可以尝试一下,贴到浏览器中,找到 cid 参数,修改为另外一个值。如果没有工具,这个过程是很痛苦的。一次还好,如果一天重复这个动作几十次,就有必要考虑借助工具了。

    基于这个出发点,我制作了 URLHelper 这个扩展,它的界面大概长这个样子,可以非常方便的对 URL 参数进行删查改排序,修改参数刷新页面:

    新葡亰496net 5

    所以,扩展程序我觉得每个前端都可以开发,用于解决我们工作生活中在使用浏览器遇到的各种问题,譬如有名的 :

    • WEB 前端助手 提供的字符串编码、JSON 格式化
    • PageSpeed 提供的页面性能检测等等
    • 二维码生成器 将 URL 转化成对应的二维码

     

    什么是 chrome 扩展程序

    扩展程序是一些能够修改或增强 Chrome 浏览器功能的小程序。对于前端工程师而言,其最大的便利就是我们可以应用我们熟悉的 HTML、CSS 、 Javascript 等技术来制作扩展程序。

    如下图所示,这些图标就是各种开发者提供的 chrome 扩展程序:

    新葡亰496net 6

    • 这次做这个插件的功能很简单,就是点击按钮后可以对当前网页的模块进行选择隐藏。
    • 做这个插件一方面是练习实例,还有一方面是,有的时候查资料啊,边上总有很多花花绿绿动来动去的小广告!
    • 很烦有木有,还根本不能关闭!就算有关闭按钮,点击了竟然还跳转到广告页面了(゚Д゚≡゚Д゚)
    • 所以就想做个小插件,让自己可以选择隐藏这些不想看的模块。

    数据保存及隐身模式

    可以使用HTML5的localStorage或保存到服务器,但是,无论何种方式,尽量保证在隐身模式的情况下不要保存任何数据,或仅将数据保存在内存中,如下:

    function saveTabData(tab, data) {
      if (tab.incognito) {
        chrome.runtime.getBackgroundPage(function(bgPage) {
          bgPage[tab.url] = data;      // 匿名模式,保存为当前页面的数据,只在内存中
        });
      } else {
        localStorage[tab.url] = data;  // 保存到本地
      }
    }
    

    扩展程序架构

    OK,接下来聊聊一些扩展程序开发相关的东西。

    关于扩展程序的相关文档,可以看看这些文章:

    • 建立 Chrome 扩展程序
    • 扩展开发文档

    首先,我觉得最重要的,是要了解整个扩展程序的基本架构,有几个非常重要的文件:

     

    配置文件

    调试

    插件各部分的调试方式各不相同,具体如下:

    • Content script:直接F12打开开发者工具,在Sources栏下的Content scripts即可调试
    • background:在chrome的扩展程序设置页面chrome://extention 下找到相应的插件,点击检查视图即可调试
    • popup:右击工具栏上插件的图标,选择审查弹出内容即可调试

    区分扩展与插件

    很多人会误称扩展程序为插件,这里有必要区分一下。

    "扩展" 和 "插件",其实都是软件组件的一种形式,Chrome 只不过是把两种类型的组件分别给与了专有名称,一个叫 "扩展",另一个叫 "插件"。

    • 扩展(Extension)

    指的是通过调用 Chrome 提供的 Chrome API 来扩展浏览器功能的一种组件,工作在浏览器层面,使用 HTML Javascript 语言开发。比如著名的 Adblock plus。

    • 插件(Plug-in)

    指的是通过调用 Webkit 内核 NPAPI 来扩展内核功能的一种组件,工作在内核层面,理论上可以用任何一种生成本地二进制程序的语言开发,比如 C/C 、Delphi 等。比如 Flash player 插件,就属于这种类型。一般在网页中用 <object> 或者 <embed>标签声明的部分,就要靠插件来渲染。

     

    每一个扩展都有一个JSON格式的manifest文件,叫manifest.json。

    Chrome API

    除了web本身的API以外,Chrome插件还支持一些独有的API可供使用

    • 同步方法vs异步方法
      例:
      同步方法:返回string的chrome.runtime.getURL()方法
      异步方法:
       //获取当前页面,并修改页面url
       chrome.tabs.query({'active': true}, function(tabs) {
       chrome.tabs.update(tabs[0].id, {url: newUrl});
       });
    
    • 常用API:
      • chrome.extension.getURL():获取插件文件的URL,
        例:chrome.extension.getURL("images/myimage.png");获取文件myimage.png的URL
      • chrome.tabs.executeScript():向访问页面注入脚本

    最后附上一个我自己用的两个小demo,一个可以自动调整简书文章页面的宽度,一个可以修改页面样式:
    简书调宽:https://github.com/rascalquan/JianShuNoteWidth

    新葡亰496net 7

    简书调宽.png

    CSS修改器:https://github.com/rascalquan/ChangePageStyle

    新葡亰496net 8

    Paste_Image.png

    Content scripts — 内容脚本

    Content scripts 脚本是指能够在浏览器已经加载的页面内部运行的 javascript 脚本。可以将 content script 看作是网页的一部分,而不是它所在的扩展程序的一部分。

    它可以实现的一些功能的例子及适用场景,大致如下:

    • 在网页中找出未链接的 URL,并将它们转换为超链接
    • 查找特定的信息或者 DOM 结构,增加字体大小,使文本更具有可读性
    • 发现并处理 DOM 中的微格式数据

    我们可以这样理解它,在页面加载完毕之后,我们的扩展程序会向这个页面注入一个或者额多个脚本,这个脚本可以获得浏览器所访问的 web 页面的详细信息。也就是我们可以利用这个脚本收集页面上各种我们需要的信息。

    以我上面的 URLHelper 为例子,在这个扩展中,content script 的作用就是拿到页面的 URL ,然后传递给扩展程序的 background 页面或者 popup 页面。

    当然,如果你只需要一个脚本程序每次注入页面后获取页面相关的信息,然后上报到自己的服务器之类的功能,这个扩展程序只需要这一个 Content scripts 就够了。它不需要与其他界面或者脚本进行交互和信息传递,扩展帮你做的就是自动注入这个脚本而需要你每次手动注入。

    开发自己的扩展程序

    OK,简单了解完什么是扩展程序后,下面我们来看看如何开发一款扩展程序。

    当然,首先我们要搞清楚为什么我们需要扩展程序,它有什么作用呢?

    就我而言,最近我开发了一款简单的扩展程序 —— URLHelper 。你可以在 chrome 应用商店下载到它:

    新葡亰496net 9

    开发它的原因是因为,在我们的业务开发中,开发过程经常需要面对超长的 URL,带有 N 多个参数,它可能长这样:

    http://tv.video.qq.com/xxx/xxx/xxx/index?rootdomain=test.tv.video.qq.com&guid=066de07bdd33422f95b7ddaf993b2004&tvid=0930DCE900E081E142ED006B56025BA7&appver=3.1.0&bid=31001&appid=101161688&vipbid=38&fromvipbid=38&cid=qk97pyegxz8kdug&vid=&pid=&mid=&from=501&qua_info=PT=SNMAPP&CHID=10009&VN=3.1.0&PR=VIDEO&TVKPlatform=670603&SMARKET=&type=0&listid=&matchid=&channelid=&source1=747&source2=709&penid=D21D81E4489E43422F842235B52DD&access=82E8E64DDD4A531B6FFA3E0967F76&kt_login=qq&vuserid=&vusession=&oauth_consumer_key=101161688&kt_userid=924400965&kt_license_account=SNM_0059858531&main_login=qq&kt_login_support=qq,wx,ph&kt_boss_channel=tx_snm&ott_flag=2&sop=9&actid=&tvactid=&tv_params=policy_id=88&disable_update=&dp=&du=&viewid=&dv=&pageid=&ptag=&redirect_url=http://test.tv.video.qq.com/ktweb/pay/phone/scan?rootdomain=test.tv.video.qq.com&guid=066de07bdd33422f95b7ddaf993b2004&tvid=0930DCE900E081E142ED006B56025BA7&appver=3.1.0&bid=31001&appid=101161688&vipbid=38&fromvipbid=38&cid=qk97pyegxz8kdug&vid=&pid=&mid=&from=501&qua_info=PT%3DSNMAPP%26CHID%3D10009%26VN%3D3.1.0%26PR%3DVIDEO%26TVKPlatform%3D670603%26SMARKET%3D&type=0&listid=&matchid=&channelid=&source1=747&source2=709&openid=D21D81E44801E9E43422F842235B52DD&access_token=82E8E64DDD4EDA531B6FFA3E09676F76&kt_login=qq&vuserid=&vusession=&oauth_consumer_key=101161688&kt_userid=924400965&kt_license_account=SNM_0059858531&main_login=qq&kt_login_support=qq%2Cwx%2Cph&kt_boss_channel=tx_snm&ott_flag=2&sop=9&actid=&tvactid=&tv_params=policy_id%3D88&disable_update=&dp=&du=&viewid=&dv=&pageid=&ptag=&opres=0&$from=201
    

    不是开玩笑,真实情况可能比这个还长。新葡亰496net 10

    因为调试的需要,经常要找到某一个特定的参数,获取或者修改它的值。

    读者可以尝试一下,贴到浏览器中,找到 cid 参数,修改为另外一个值。如果没有工具,这个过程是很痛苦的。一次还好,如果一天重复这个动作几十次,就有必要考虑借助工具了。

    基于这个出发点,我制作了 URLHelper 这个扩展,它的界面大概长这个样子,可以非常方便的对 URL 参数进行删查改排序,修改参数刷新页面:

    新葡亰496net 11

    所以,扩展程序我觉得每个前端都可以开发,用于解决我们工作生活中在使用浏览器遇到的各种问题,譬如有名的 :

    • WEB 前端助手 提供的字符串编码、JSON 格式化
    • PageSpeed 提供的页面性能检测等等
    • 二维码生成器 将 URL 转化成对应的二维码

     

    所以第一步我们将创建一个manifest.json文件。如下:

    扩展程序架构

    OK,接下来聊聊一些扩展程序开发相关的东西。

    关于扩展程序的相关文档,可以看看这些文章:

    • 建立 Chrome 扩展程序
    • 扩展开发文档

    首先,我觉得最重要的,是要了解整个扩展程序的基本架构,有几个非常重要的文件:

    {      "manifest_version": 2, //固定的     "name": "Cissy's First Extension", //插件名称     "version": "1.0", //插件使用的版本     "description": "The first extension that CC made.", //插件的描述     "browser_action": { //插件加载后生成图标         "default_icon": "cc.gif",//图标的图片         "default_title": "Hello CC", //鼠标移到图标显示的文字          "default_popup": "popup.html" //单击图标执行的文件     },      "permissions": [ //允许插件访问的url         "http://*/",          "bookmarks",          "tabs",          "history"      ],      "background":{//background script即插件运行的环境         "page":"background.html"         // "scripts": ["js/jquery-1.9.1.min.js","js/background.js"]//数组.chrome会在扩展启动时自动创建一个包含所有指定脚本的页面     },       "content_scripts": [{  //对页面内容进行操作的脚本          "matches": ["http://*/*","https://*/*"],  //满足什么条件执行该插件           "js": ["js/jquery-1.9.1.min.js", "js/js.js"],             "run_at": "document_start",  //在document加载时执行该脚本     }]  } 
    

    popup — 弹窗页面

    popup 页面也非常好理解,在 manifest.json 的定义里它是 browser_action, 就是我们扩展程序的界面(弹窗页),就是上面的那张截图:

    新葡亰496net 12

    这个界面其实就是一个 Web 页面,点开任意一个扩展页面,右键都可以看到弹出检查选项,点击这个选项,就会弹出一个开发者工具,我们就可以愉快的开始对这个页面进行查看 DOM 结构、查看网络状态、 Debug 等任意操作了:

    新葡亰496net 13

    然后:

    新葡亰496net 14

    重点,这个 popup 页面完全由我们控制,就像一个普通的 Web 页面,我们可以利用 Chrome 的消息传递机制利用这个页面和 Content scripts 进行交互,也就可以完成对页面的某些控制。

    以我上面的 URLHelper 为例子,在这个扩展中,当我点击扩展程序界面中的刷新页面按钮的时候,会从扩展界面的 DOM 上将修改后参数取出拼好,并且通过 Chrome 的消息传递机制 传递给 Content scripts,然
    后 Content scripts 拿到新的参数,赋值给当前浏览器窗口页面的 document.location.href,实现页面的刷新。

     

    每个字段的信息我都用注释标明了,接下来就重点说下一些重要字段。

    Content scripts -- 内容脚本

    Content scripts 脚本是指能够在浏览器已经加载的页面内部运行的 javascript 脚本。可以将 content script 看作是网页的一部分,而不是它所在的扩展程序的一部分。

    它可以实现的一些功能的例子及适用场景,大致如下:

    • 在网页中找出未链接的 URL,并将它们转换为超链接
    • 查找特定的信息或者 DOM 结构,增加字体大小,使文本更具有可读性
    • 发现并处理 DOM 中的微格式数据

    我们可以这样理解它,在页面加载完毕之后,我们的扩展程序会向这个页面注入一个或者额多个脚本,这个脚本可以获得浏览器所访问的 web 页面的详细信息。也就是我们可以利用这个脚本收集页面上各种我们需要的信息。

    以我上面的 URLHelper 为例子,在这个扩展中,content script 的作用就是拿到页面的 URL ,然后传递给扩展程序的 background 页面或者 popup 页面。

    style="font-family: verdana, geneva; font-size: 14px;">当然,如果你只需要一个脚本程序每次注入页面后获取页面相关的信息,然后上报到自己的服务器之类的功能,这个扩展程序只需要这一个 Content scripts 就够了。它不需要与其他界面或者脚本进行交互和信息传递,扩展 style="font-family: verdana, geneva; font-size: 14px;">帮你做的就是自动注入这个脚本而需要你每次手动注入。

    需要注意:

    background — 后台网页

    除了 popup 页面之外,还有一个 background 后台网页 。

    chrome扩展程序将后台网页分为两种类型:

    • 持续运行的后台网页
    • 事件页面

    是否持久存在是事件页面与后台网页之间的根本区别。(刚开始使用的时候可以理解为一个东西)

    应用和扩展程序通常需要长时间运行的脚本来管理某些任务或状态,这就是后台页面的作用。事件页面只在需要时加载,当事件页面不活动时就会卸载,以便释放内存和其他系统资源,所以一般而言是推荐使用事件页面。

    它存在的目的在于,在扩展的整个生命周期内需要长时间管理一些任务或状态。它的主要功能及适用场景,大致如下:

    • 事件页面监听的某个事件触发
    • 应用或扩展程序第一次安装或者更新到新版本(为了注册事件)
    • 内容脚本或其他扩展程序发送消息
    • 扩展程序中的其他视图调用了 runtime.getBackgroundPage

    以我上面的 URLHelper 为例子,在这个扩展中,我使用的是持续运行的后台网页,当浏览器页面刷新第一次注入 Content Script 时,会获取到当前页面 url ,然后发送消息并带上 url 信息告诉给 background 后台网页, background 后台网页收到消息后,再转发给 popup 页面。

     

    chrome不允许扩展中的HTML页面内直接内嵌js脚本,而要求所有的脚本都作为外部src来引入

    popup -- 弹窗页面

    popup 页面也非常好理解,在 manifest.json 的定义里它是 browser_action, 就是我们扩展程序的界面(弹窗页),就是上面的那张截图:

    新葡亰496net 15

    这个界面其实就是一个 Web 页面,点开任意一个扩展页面,右键都可以看到弹出检查选项,点击这个选项,就会弹出一个开发者工具,我们就可以愉快的开始对这个页面进行查看 DOM 结构、查看网络状态、 Debug 等任意操作了:

    新葡亰496net 16

    然后:

    新葡亰496net 17

    重点,这个 popup 页面完全由我们控制,就像一个普通的 Web 页面,我们可以利用 Chrome 的消息传递机制利用这个页面和 Content scripts 进行交互,也就可以完成对页面的某些控制。以我上面的 URLHelper 为例子,在这个扩展中,当我点击扩展程序界面中的刷新页面按钮的时候,会从扩展界面的 DOM 上将修改后参数取出拼好,并且通过 Chrome 的消息传递机制 传递给 Content scripts,然

    后 Content scripts 拿到新的参数,赋值给当前浏览器窗口页面的 document.location.href,实现页面的刷新。

    browser_action

    扩展程序小结

    一个扩展程序最重要的我觉得就是上述的三块内容:

    • Content scripts — 内容脚本
    • popup — 弹窗页面
    • background — 后台网页

    新葡亰496net 18

    我们通过一个 manifest.json新葡亰496net, 的清单文件来配置它们及一些额外信息。关于 manifest.json 的详细信息,可以戳:manifest 。

    接下来,我们的扩展要灵活地完成各种功能,最重要的就是互相间的通信!

    信息数据在内容脚本、弹窗页面以及事件页面之间传递是一个扩展程序最重要的部分。

     

    1. 如果browser action拥有一个popup(即设置了default_popup),popup 可以包含任意你想要的HTML内容,并且会自适应大小。popup 会在用户点击图标后出现。若没有设置default_popup,将执行chrome.browserAction.onClicked的内容,若没有设置,就什么都不执行了。也就是如果设置了default_popup,就不会执行chrome.browserAction.onClicked了。
    2. 和browser_action对应的还有一个page_action,区别在于:Browser Action对在浏览器中加载的所有网页都生效;Page Action针对特定的网页生效。一个Extension最多可以有一个Browser Action或者Page Action。这里选用Browser Action。

    扩展程序的消息传递

    消息传递存在的必要性是因为内容脚本在网页而不是扩展程序的环境中运行,所以它们通常需要某种方式与扩展程序的其余部分通信。

    扩展程序(弹窗页面和后台页面)和内容脚本间的通信使用消息传递的方式。两边均可以监听另一边发来的消息,并通过同样的通道回应。消息可以包含任何有效的 JSON 对象。

    background -- 后台网页

    除了 popup 页面之外,还有一个 background 后台网页 。

    chrome扩展程序将后台网页分为两种类型:

    • 持续运行的后台网页
    • 事件页面

    是否持久存在是事件页面与后台网页之间的根本区别。(刚开始使用的时候可以理解为一个东西)

    应用和扩展程序通常需要长时间运行的脚本来管理某些任务或状态,这就是后台页面的作用。事件页面只在需要时加载,当事件页面不活动时就会卸载,以便释放内存和其他系统资源,所以一般而言是推荐使用事件页面。

    它存在的目的在于,在扩展的整个生命周期内需要长时间管理一些任务或状态。它的主要功能及适用场景,大致如下:

    • 事件页面监听的某个事件触发
    • 应用或扩展程序第一次安装或者更新到新版本(为了注册事件)
    • 内容脚本或其他扩展程序发送消息
    • 扩展程序中的其他视图调用了 runtime.getBackgroundPage

    以我上面的 URLHelper 为例子,在这个扩展中,我使用的是持续运行的后台网页,当浏览器页面刷新第一次注入 Content Script 时,会获取到当前页面 url ,然后发送消息并带上 url 信息告诉给 background 后台网页, background 后台网页收到消息后,再转发给 popup 页面。

    background

     

    1. background是插件的运行环境。若设置了scripts字段,浏览器的扩展系统会自动根据scripts字段指定的所有js文件自动生成背景页。也可以直接page字段,指定背景页。两者只能设置一个。
    2. 一般情况下,我们会让将扩展的主要逻辑都放在 background 中比较便于管理。其它页面可以通过消息传递的机制与 background 进行通讯。理论上 content script 与 popup 之间也可以传递消息,但不建议这么做。

    使用 chrome.* API

    消息传递,主要使用了 Chrome 浏览器的内置 chrome 对象进行。打开浏览器,试一下,chrome 对象其实包含了非常多的功能:

    新葡亰496net 19

    各种类型的消息传递都是通过这个 chrome 对象进行,分为:

    • 简单的一次性请求
    • 长时间的连接
    • 跨扩展程序消息传递
    • 从网页发送消息
    • 原生消息通信

    当然,对于通常而言的普通扩展程序而言,简单的一次性请求就足够我们使用了,举两个例子。

    假设我们的 manifest.json 简单定义如下:

    # manifest.json { "name": "Url Helper", "version": "1.0.0", "author": "Coco", "manifest_version": 2, "browser_action": { "default_popup": "popup.html" }, "background": { "scripts": ["background.js"] }, "content_scripts": [ { "js": ["contentScript.js"] } ] }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # manifest.json
    {
        "name": "Url Helper",
        "version": "1.0.0",
        "author": "Coco",
        "manifest_version": 2,
     
        "browser_action": {
            "default_popup": "popup.html"
        },
        "background": {
            "scripts": ["background.js"]
        },
        "content_scripts": [
            {
                "js": ["contentScript.js"]
            }
        ]
    }

    扩展程序小结

    一个扩展程序最重要的我觉得就是上述的三块内容:

    • Content scripts -- 内容脚本
    • popup -- 弹窗页面
    • background -- 后台网页

    新葡亰496net 20

    我们通过一个 manifest.json 的清单文件来配置它们及一些额外信息。关于 manifest.json 的详细信息,可以戳:manifest 。

    接下来,我们的扩展要灵活地完成各种功能,最重要的就是互相间的通信!

    信息数据在内容脚本、弹窗页面以及事件页面之间传递是一个扩展程序最重要的部分。

    消息传递

     

    由于插件的js运行环境有区别,所以消息传递机制是一个重要内容。

    从 Content Script 向 background 事件页面 传递消息

    • Content Script ,即是注入页面的脚本

    # contentScript.js // 发送消息 chrome.runtime.sendMessage( { msg: '从 Content Script 向 事件页面 传递消息', result: 1 }, function(response) { if (response && response.msg) { console.log(response.msg); } } );

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # contentScript.js
     
    // 发送消息
    chrome.runtime.sendMessage(
    {
    msg: '从 Content Script 向 事件页面 传递消息',
    result: 1
    },
    function(response) {
    if (response && response.msg) {
    console.log(response.msg);
    }
    }
    );
    • background 后台页面

    #background.js // 接收消息 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.result) { sendResponse({ farewell: "ok" }); } });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #background.js
     
    // 接收消息
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
        if (request.result) {
            sendResponse({
                farewell: "ok"
            });
        }
    });

    在发送端,我们可以使用 runtime.sendMessagetabs.sendMessage 方法。这些方法分别允许您从内容脚本向扩展程序或者反过来发送可通过 JSON 序列化的消息,可选的 callback 参数允许您在需要的时候从另一边处理回应。

    而在接收端,我们需要设置一个 runtime.onMessage 事件监听器来处理消息。

    扩展程序的消息传递

    消息传递存在的必要性是因为内容脚本在网页而不是扩展程序的环境中运行,所以它们通常需要某种方式与扩展程序的其余部分通信。

    扩展程序(弹窗页面和后台页面)和内容脚本间的通信使用消息传递的方式。两边均可以监听另一边发来的消息,并通过同样的通道回应。消息可以包含任何有效的 JSON 对象。

    一次简单的请求

     

    如果仅需要给你自己的扩展的另外一部分发送一个消息(可选的是否得到答复),你可以简单地使用chrome.extension.sendRequest()或者chrome.tabs.sendRequest()方法。这个方法可以帮助你传送一次JSON序列化消息从content script到扩展,反之亦然。如果接受消息的一方存在的话,可选的回调参数允许处理传回来的消息。

    从 popup 弹窗页面 向 Content Script 传递消息

    再举一个翻过来的例子,从 popup 弹窗页面 向 Content Script 传递消息。

    • popup 弹窗页面

    # popup.html 页面内引入的 popup.js let obj = { msg: '从 popup 弹窗页面 向 Content Script 传递消息', result: 0 }; // 发送消息 chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) { chrome.tabs.sendMessage(tabs[0].id, obj, function(response) { console.log("Send Success"); }); });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # popup.html 页面内引入的 popup.js
     
    let obj = {
        msg: '从 popup 弹窗页面  向 Content Script 传递消息',
        result: 0
    };
     
    // 发送消息
    chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, obj, function(response) {
            console.log("Send Success");
        });
    });
    • Content Script

    # contentScript.js // 接收消息 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { console.log(sender.tab ? "来自内容脚本:" sender.tab.url : "来自扩展程序"); if (request && !request.result) { console.log(result.msg); } });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # contentScript.js
     
    // 接收消息
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log(sender.tab ? "来自内容脚本:" sender.tab.url : "来自扩展程序");
     
    if (request && !request.result) {
    console.log(result.msg);
    }
    });

    这里有个问题需要注意,从 popup 弹窗页面 向 Content Script 传递消息时,由于浏览器可能同时打开多个 tab 页,所以需要指定一下传递的页面,指定发送至哪一个标签页。

    使用 chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {}) 则能正确选中当前打开的标签页。

    其他更多的消息传递方式,可以戳这里:消息传递。

    使用 chrome.* API

    消息传递,主要使用了 Chrome 浏览器的内置 chrome 对象进行。打开浏览器,试一下,chrome 对象其实包含了非常多的功能:

    新葡亰496net 21

    各种类型的消息传递都是通过这个 chrome 对象进行,分为:

    • 简单的一次性请求
    • 长时间的连接
    • 跨扩展程序消息传递
    • 从网页发送消息
    • 原生消息通信

    当然,对于通常而言的普通扩展程序而言,简单的一次性请求就足够我们使用了,举两个例子。

    假设我们的 manifest.json 简单定义如下:

    # manifest.json
    {
        "name": "Url Helper",
        "version": "1.0.0",
        "author": "Coco",
        "manifest_version": 2,
    
        "browser_action": {
            "default_popup": "popup.html"
        },
        "background": {
            "scripts": ["background.js"]
        },
        "content_scripts": [
            {
                "js": ["contentScript.js"]
            }
        ]
    }
    

    sendRequest() 是Chrome33之前的API,33之后还是使用sendMessage()吧。

    将扩展程序打包上线发布到 Chrome 应用商店

    扩展程序开发好了,希望供他人下载。那么当然需要发布到应用商店。流程大致如下:

     

    1.内容脚本发送消息到扩展程序

    从 Content Script 向 background 事件页面 传递消息

    • Content Script ,即是注入页面的脚本

      # contentScript.js

      // 发送消息 chrome.runtime.sendMessage( { msg: '从 Content Script 向 事件页面 传递消息', result: 1 }, function(response) { if (response && response.msg) { console.log(response.msg); } } );

    • background 后台页面

      #background.js

      // 接收消息 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {

      if (request.result) {
          sendResponse({
              farewell: "ok"
          });
      }
      

      });

    在发送端,我们可以使用 runtime.sendMessage 或 tabs.sendMessage 方法。这些方法分别允许您从内容脚本向扩展程序或者反过来发送可通过 JSON 序列化的消息,可选的 callback 参数允许您在需要的时候从另一边处理回应。

    而在接收端,我们需要设置一个 runtime.onMessage 事件监听器来处理消息。

    chrome.extension.sendMessage({hello: "Cissy"}, function(response) { console.log(response.farewell); }); 
    

    登录到 Chrome 开发者信息中心。

    首先,你需要有一个 Google 帐号,点击这里
    ,登录网上应用商店。

     

    2.扩展程序发送消息到内容脚本

    从 popup 弹窗页面 向 Content Script 传递消息

    再举一个翻过来的例子,从 popup 弹窗页面 向 Content Script 传递消息。

    • popup 弹窗页面

      # popup.html 页面内引入的 popup.js

      let obj = {

      msg: '从 popup 弹窗页面  向 Content Script 传递消息',
      result: 0
      

      };

      // 发送消息 chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {

      chrome.tabs.sendMessage(tabs[0].id, obj, function(response) {
          console.log("Send Success");
      });
      

      });

    • Content Script

      # contentScript.js

      // 接收消息 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { console.log(sender.tab ? "来自内容脚本:" sender.tab.url : "来自扩展程序");

      if (request && !request.result) { console.log(result.msg); } });

    这里有个问题需要注意,从 popup 弹窗页面 向 Content Script 传递消息时,由于浏览器可能同时打开多个 tab 页,所以需要指定一下传递的页面,指定发送至哪一个标签页。

    使用 chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {}) 则能正确选中当前打开的标签页。

    其他更多的消息传递方式,可以戳这里:消息传递。

    chrome.tabs.sendMessage(tab.id, {hello: "Cissy"}, function(response) { console.log(response.farewell); }); 
    

    添加一个新项并以 zip 文件的形式上传文件。

    成功之后,将会登录到这个界面,: 新葡亰496net 22

    在这个界面我们选择添加新内容即可 : 新葡亰496net 23

    注意,要打包成 *.zip 格式,并且在根目录下有最重要的 manifest.json 文件,像我上传的整个目录结构,就非常简单:
    新葡亰496net 24

     

    3.接收消息

    将扩展程序打包上线发布到 Chrome 应用商店

    扩展程序开发好了,希望供他人下载。那么当然需要发布到应用商店。流程大致如下:

    chrome.extension.sendMessage()向扩展内的其它监听者发送一条消息。此消息发送后会触发扩展内每个页面的chrome.extension.onMessage()事件。

    首次发布,需要支付 5 美刀

    选择文件并且成功上传之后,下一步非常重要。第一次发布扩展程序,谷歌会收取 $5 开发者注册费用,之后可以发布 20 个扩展程序 。

    新葡亰496net 25
    新葡亰496net 26

    这里付款中国内地的银行卡好像都不行,只能选择国外的 VISA 等储蓄卡、信用卡进行支付,地区选择美国即可。

     

    我用的是长时间的保持连接,原理差不多,就是调用接口的区别,所以就不具体介绍这个了 详细的可以看开发文档

    登录到 Chrome 开发者信息中心。

    首先,你需要有一个 Google 帐号,点击这里,登录网上应用商店。

    长时间的保持连接

    付款完成,可以愉快的发布了

    OK,最后付款完成,就可以顺利发布了,稍等片刻,就可以搜索到我们自己开发扩展程序了!

     

    background 和 popup

    后记

    其实开发一款 Chrome 扩展程序真的不难,而且非常有意思。感兴趣但又怕麻烦的同学可以参考我这个小项目改改。Github — URL Helper

    好了,本文到此结束,希望对你有帮助 :)

    如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

    打赏支持我写出更多好文章,谢谢!

    打赏作者

    添加一个新项并以 zip 文件的形式上传文件。

    成功之后,将会登录到这个界面,: 新葡亰496net 27

    在这个界面我们选择添加新内容即可 : 新葡亰496net 28

    注意,要打包成 *.zip 格式,并且在根目录下有最重要的 manifest.json 文件,像我上传的整个目录结构,就非常简单:
    新葡亰496net 29

    同一个Extension的Extension Page(包括background、popup、tab、infobar、notification)都是运行在同一个进程中的,所以background 和 popup 之间可以直接相互调用对方的方法,不需要消息传递。

    打赏支持我写出更多好文章,谢谢!

    任选一种支付方式

    新葡亰496net 30 新葡亰496net 31

    1 赞 1 收藏 评论

     

    1.popup调用background中变量或方法

    关于作者:chokcoco

    新葡亰496net 32

    经不住流年似水,逃不过此间少年。 个人主页 · 我的文章 · 63 ·    

    新葡亰496net 33

    首次发布,需要支付 5 美刀

    选择文件并且成功上传之后,下一步非常重要。第一次发布扩展程序,谷歌会收取 $5 开发者注册费用,之后可以发布 20 个扩展程序 。

    新葡亰496net 34
    新葡亰496net 35

    这里付款中国内地的银行卡好像都不行,只能选择国外的 VISA 等储蓄卡、信用卡进行支付,地区选择美国即可。(寻找身边有 VISA 卡的小伙伴帮忙支付即可)

    var bg = chrome.extension.getBackgroundPage();//获取background页面 console.log(bg.a);//调用background的变量或方法。 
    

     

    2.background调用popup中变量或方法

    付款完成,可以愉快的发布了

    OK,最后付款完成,就可以顺利发布了,稍等片刻,就可以搜索到我们自己开发扩展程序了!

    var pop = chrome.extension.getViews({type:'popup'});//获取popup页面 console.log(pop[0].b);//调用第一个popup的变量或方法。 
    

     

    这里要注意一定要指明type,如果没有指定,则获取Background Page之外的所有Extension Page的window对象 。(。•ˇ‸ˇ•。)这个地方真的纠结好久。然后就是background是一个运行在扩展进程中的HTML页面。它在你的扩展的整个生命周期都存在,而popup是在你点击了图标之后才存在,所以,在获取popup变量时,请确认popup已打开。

    仅供开发使用

    当然,有些同学无法访问谷歌商店,或者扩展程序做出来仅仅是团队内部的一种工具,供私人使用。那么可以直接在 chrome 浏览器安装安装包。

    • 在 chrome 浏览器中访问 chrome://extensions(或者单击多功能框最右边的按钮:打开 Chrome 浏览器菜单,并选择更多工具 (L) 菜单下的扩展程序 (E),进入相同的页面)。
    • 确保右上角开发者模式复选框已选中,单击加载已解压的扩展程序 …,弹出文件选择对话框。
    • 浏览至您的扩展程序文件所在的目录,并选定。

    style="font-size: 14px; font-family: verdana, geneva;">扩展目录即是一个项目下的所有文件,开发调试时同理安装即可。

    background 和 content

      

    持续长时间的保持会话需要在content script和扩展建立一个长时间存在的通道。当建立连接,两端都有一个Port 对象通过这个连接发送和接收消息。

    后记

    其实开发一款 Chrome 扩展程序真的不难,而且非常有意思。感兴趣但又怕麻烦的同学可以参考我这个小项目改改。Github -- URL Helper

    好了,本文到此结束,希望对你有帮助 :)

    如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

    1.内容脚本发送消息到扩展程序

    var bac = chrome.extension.connect({name: "ConToBg"});//建立通道,并给通道命名 bac.postMessage({hello: "Cissy"});//利用通道发送一条消息。 
    

    2.扩展程序发送消息到内容脚本扩展程序发送消息到内容脚本与前面类似,但需要指定哪个标签需要连接,(获取tab.id的方法我试了很多,但只有下面这个有效,所以如果大家有什么其他有效的方法,求求求分享!!)

    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {//获取当前Tab var cab = chrome.tabs.connect(tabId, {name: "BgToCon"});//建立通道,指定tabId,并命名 cab.postMessage({ hello: "Cissy"});//利用通道发送一条消息。 } 
    

    3.接收消息为了处理正在等待的连接,需要用chrome.extension.onConnect 事件监听器,对于content script或者扩展页面,这个方法都是一样的

    chrome.extension.onConnect.addListener(function(bac) {//监听是否连接,bac为Port对象 bac.onMessage.addListener(function(msg) {//监听是否收到消息,msg为消息对象 console.log(msg.hello); }) }) 
    

    安装调试

    设置 —>拓展程序—>加载已解压的拓展程序—>选择文件就行了,记得要打开开发者模式哦

    总结

    插件功能的开发我就不写了,实现起来比较简单,这篇文章就当是chrome拓展开发的学习笔记了,不足之处还望指出,最后还是放一下插件源码吧,写的比较乱很多没用到的代码也没删掉,因为是练习中用到的。嗯嗯好了去吃饭。

    【编辑推荐】

    本文由新葡亰496net发布于新葡亰官网,转载请注明出处:新葡亰496net:Chrome插件开辟计算,手把手教你付

    关键词: