博客> 与 Safari Extension 和 Chrome Extension 的二三事
与 Safari Extension 和 Chrome Extension 的二三事
2017-09-24 09:17 评论:0 阅读:281 virus1993
Safari ios extension Content Blocker

前言

一直以来对 js 和 html 无感,但是经常上的某网站有很多广告,虽然有 Adb 之类的大杀器,但是只能说去除一部分广告,而且有些很烦人的控件一直乱悬浮让人很无语,总的来说就是大部分的广告和烦人的控件无法通过大杀器屏蔽。于是乎作为一个半强迫症的人(嘿嘿),必须实现自己的广告杀器!

本文详细介绍了 Safari 的扩展插件开发,并在 Chrome 实现了相同的扩展插件开发

Safari 篇

好的,开始吧!

要做成什么样的 Extenions?

能拦截该网站所有不想看到的广告 能修改任意 css 样式 以上功能在 Safari 中实现并且支持 Mac 和 iOS 平台

好的, 那就查找资料吧!(其实本文能实现js脚本的注入,但是现在的需求是内容拦截与样式修改)

资料来源

既然要在 Safari 上开发扩展插件,自然要从苹果开发者网站查找相关文档

Safari Extenions 开发主页: https://developer.apple.com/safari/extensions/

Content Blocker 视频讲解: https://developer.apple.com/videos/play/wwdc2015/511/

Safari Extenions 开发具体细节: https://developer.apple.com/library/prerelease/content/documentation/NetworkingInternetWeb/Conceptual/SafariAppExtension_PG/

以上的资料是最权威的,当然我也有很多看不懂的地方,这时候就是各种搜索引擎帮助查找到各种具体的示例和各种错误的解决,但是,最后,都得回到上面几个网站,因为所有示例都是以它为准,很多问题的根本答案隐藏在官方文档中

根据资料我们可以知道苹果的 Extenions 支持如下功能扩展

任意内容拦截(Content blocker),不支持原生代码交互             
注入多个任意 CSS 样式(Inject CSS Style Sheet)              
注入多个 js 脚本(Inject Javascript),并可与原生代码交互       
**以上功能均可以根据 url 规则控制是否针对指定站点生效**           

根据多年的开发经验,苹果真的是非常良心,所要的功能都提供了!

好的,权威资料有了,开始动手吧!

开发环境

这里我就斗胆的不使用正式版开发工具了,哈哈(任性)

  • Xcode 9 Beta 6
  • macOS High Sierria Beta 10.13
  • iOS 11 Beta
  • Swift 4 Beta

搬砖流程

下面就是开发的具体流程

新建工程

这里我们新建一个名为 SPABlocker 的 Mac Application,其他选项可以默认

new project

new project

然后可以看到我们只是新建了一个 Mac 应用程序,因为 Extensions 必须要宿主程序,但是怎么添加 Extensions,没有开发过 Extensions 的同学可能不知道,其实在工程里面扩展是一个 Target,因此我们只要进入工程设置页面,也就是这里
new project
target 列表下方有个加号 ( + ),点击以后就可惜新建 target 了,这么我们选择 macOS 下的 Content Extension BlockerProduct Name 我们就叫做 ADBoomer

new project

然后会 提示是否要 Activate, 当然是 Activate 了!

new project

  • 添加以后我们会在工程目录里面看到多了一个 ADBoomer 的目录,所有这个扩展的功能代码都在里面
    1. 它有自己的 info.plist
    2. blockerList.json 是拦截规则
    3. ContentBlockerRequestHandler.swift 是初始化的原生代码, 这里载入拦截规则的 json 文件,我们可以在里面做自己的一些改动,比如 json 文件从网络获取,或者修改规则

new project

ADBoomer 对我们来说只是一个内容拦截器,它只负责拦截广告

好了,工程搭建起来了! 接下来就开始分析广告拦截吧!

网站广告代码分析

分析代码之前,我们得知道如下拦截规则

{
  "action": {
   "type": "css-display-none",
   "selector":"a.qd-block"
  },
  "trigger": {
   "if-domian":["baidu.com", "sex8.cc"],
   "url-filter": ".*"
  }
}

json 文件里面是个数组,数组元素是字典,上面这个字典是一条拦截规则,它主要说明两点

哪些情况会触发规则

规则执行说明操作

这条规则意思是当站点为 baidu.comsex8.cc 时触发该规则,规则要执行的动作是 css-display-none,也就是隐藏元素,是哪些元素呢?就是通过选择器的元素(class 是 qd-blocka 标签)

这样的规则是通过 css 选择器来确定要隐藏的广告元素

css 选择器参考手册 http://www.w3school.com.cn/cssref/css_selectors.asp
里面很复杂,一般要不停测试才能要到适合的规则

另外,我们还需要一条规则

 {
  "action": {
   "type": "block"
  },
  "trigger": {
   "url-filter": "http://ads.feemoo.com/*"
  }
 }

这条规则的意思是当站点前缀符合 http://ads.feemoo.com 时触发该条规则,规则执行的动作是拦截整个网页的内容

当然,还有很多的规则,我这里就不一一列举,因为这两个需求就够了,总结下来就是隐藏元素和阻止内容的加载

这两条规则是这么确定的呢?

好,我给大家看这个网站的页面

new project

可以看到这个页面一进来就充斥着广告,那我们看页面的源代码,看这个新黄金城的广告的 html 代码

new project

通过代码分析我们知道,新黄金城的广告这里是个 img 标签,但是我们仔细看就会发现只要把 class 为 full heg 的 div 元素隐藏,整条广告就消失了!,所以我们这时候就得出如下拦截规则

{
  "action": {
   "type": "css-display-none",
   "selector":".full.heg"
  },
  "trigger": {
   "if-domian":["baidu.com", "sex8.cc"],
   "url-filter": ".*"
  }
}

没错! 我们这就干掉了一条广告,接下来的规则就是分析其他广告元素的 html 代码,css 选择器很给力,有各种规则,不止class,可以是指定元素层级,style的值,taget的值等等,几乎没有干不掉的静态广告,当然,有的动态广告就需要使用 js 脚本注入的方式,但这里就不讨论了。

拦截规则官方文档 https://developer.apple.com/library/content/documentation/Extensions/Conceptual/ContentBlockingRules/CreatingRules/CreatingRules.html#//apple_ref/doc/uid/TP40016265-CH2-SW1

我已经完成了大部分的分析,下面是我写的拦截规则 json,屏蔽了很多烦人的广告和悬浮物。

https://github.com/0xfeedface1993/Xs8-Safari-Block-Extension-Mac/blob/master/Sex8BlockExtension/ADBlock/blockerList.json

好的,广告屏蔽了,那么接下来就是 css 样式的修改

CSS 自定义

要实现 css 的 inject 上面的 content blocker 做不到,这时候就要使用另一个 extension

我们再新建一个 target, 类型选择 macOS 下的 Safari Extension 的扩展, Product NameSharker,点击 Next,得记得点击 Activate

new project

new project

new project

建好工程以后,我们能看到工程目录多了一个 Sharker 的目录,里面的文件跟 ADBoomer 不一样,下面是各个文件的功能

new project

    SafariExtensionHandler.swift : 
        Bar Item 按钮事件处理,extension 安装以后会在地址栏旁边有个按钮 
    SafariExtensionViewController.swift : 
        点击 Bar Item 以后显示的页面(代码) 
    SafariExtensionViewController.xib : 
        点击 Bar Item 以后显示的页面(可视化界面) 
    Info.plist : 
        这个扩展的配置文件 
    script.js : 
         需要注入的 js 脚本,可以由多个js、css脚本,还需要在 plist 文件作相应的添加 
    ToolbarItemIcon.pdf : 
        Bar Item 按钮的图片 

我们先看 Info.plist 这个配置文件

new project

我们主要看的部分是 NSExtension 项,里面 SFSafariContentScript 就是指定注入 js 文件有哪些,那我们现在要注入 css, 所以根据文档里面的信息我们要添加一项 SFSafariStyleSheet,类型是 Array, 添加一个子项,类型是 Dictionary, 也就是说是个字典,在这个字典添加 键名Style Sheet,类型 String,值是 inject.css,这个扩展也是有作用域的,我们在 SFSafariWebsiteAccess 下的 Allowed Domains 添加需要作用的站点 如 *.baidu.com, 这样就说明该扩展在百度站点下可用

new project

这样就添加了一个注入的 css 文件,这个 inject.css 从哪里来?当然是自己写了,就是平常的 css 样式,不过要注意的是,如果想要重写某些页面存在的样式,要加 !important;, 否则无效果, 下面是示例

.thread-img {
 height:290px !important;
}

这样页面如果有 thread-img 这个样式就会重写它的 height 属性

我写好的 css 文件(改变预览图片高度,让图片更大) https://github.com/0xfeedface1993/Xs8-Safari-Block-Extension-Mac/blob/master/Sex8BlockExtension/Torrilste/inject.css

然后将编写好的 css 文件拖到工程目录下就可以了

new project

还有一点就是,一定要确定 SharkerBuild PhasesCopy Bundle Resourcesinject.css 这一项,否则扩展就无法正常工作

好了,一切准备就绪!开始测试

测试效果

接下来我们测试我们编写的内容拦截器和 css 注入是否能正常工作

首先宿主程序和扩展程序一定要经过签名,这里并不需要付费的 Apple Develoer 账户,免费的开发者账户就可以了

申请地址 https://appleid.apple.com/account?localang=en_US&appId=632&returnURL=https://idmsa.apple.com/IDMSWebAuth/login.html?language=US-EN&rv=1&path=/account/&Env=UAT&appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757#!&page=create

new project

在 Xcode 登录开发者账户后,打开项目配置,然后在 Sign 选项卡里面,点击 enable development sign,选择你的开发者账户,然后 Xcode 就自动帮你搞定证书,稍等一会如下图所示说明证书帮你弄好了

new project

SPABlockerSharker 还有 ADBoomer 都得签名!千万不要忘记

new project

Xcode 如图选择好 Scheme 和设备(我们的宿主程序 SPABlocker、这台 Mac ),选好以后开始编译运行工程(快捷键 Command + R),等到程序运行以后看到如下画面

new project

没错什么也没有,因为宿主程序什么功能都没有写。这时我们打开 Safari,打开 偏好设置 (快捷键 command + , ), 选择 扩展 选项,可以看到 SharkerADBoomer,把他们两个都勾选上,关闭 偏好设置

new project

new project

现在使用 Safari 访问我们不可描述的网站, 没错可恨的广告没有了!!!

使用前: new project

使用后:new project

再看看图文列表,图片被放大了!!

使用前:new project

使用后:new project

胜利!

想必看到这里,大家已经明白怎么开始做自己的adb插件了,我这里展示的是如何从0开始编写一个 Safari 的一个扩展,苹果在这方面做得是相当不错的,扩展性能十分好,占用资源少,因为对于内容拦截,chrome 是没有原生支持的,也就是说如果要在 chrome 上实现广告拦截,只能通过注入 js 脚本来完成,而 Safari 专门由有一个扩展类型专门做内容拦截,可以猜测原理是在解释 html、js 代码的时候进行内容的拦截,即使是注入专门的 js 脚本,也是经过特殊优化的流程。

苹果提供的功能和 chrome 差不多,但是苹果的思想依然是十分严谨的,依托于 Xcode 对项目的管理,各个模块在开发的时候就十分清晰,可惜 js 脚本还是异常的难写,总的来说专门做一个 adb 需要耗费大量的时间和经历,网站那么多,一个一个分析工作量还是很巨大的,自己用的话就适配常用的几个网站就可以了,不用再为广告烦恼。

可能看着安装步骤很复杂,其实是开发过程复杂一点,一旦开发好后,可以发布 Release 版本,就是一个 App 包,如果需要分享给其他同学,就直接复制 App 过去,打开程序就自动装上扩展插件了(需要手动打开使用)

另外还有一种方法就发布到苹果的 Extensions 商店 https://safari-extensions.apple.com

问题与注意

这个扩展插件开发过程十分曲折,开始我一度碰壁以为搞不出来了,最后各种测试猜想再测试终于弄出来了,体会就是有点嵌入式开发的感觉,和 Safari 连调的时候经常断开,错误也是千奇百怪从来没见过,但是不断学习与实践终于弄懂一二。

之所以会有这篇文章就是在自己的一个项目中关键实现就是这个 Safari Extensions,所以弄完很有感触,学到很多东西。

Chrome篇

chrome 的 extension 并没有独立的内容拦截器,也就是说要使用 js 脚本注入的方式,自己实现元素的隐藏或者移除逻辑,因为我确实对谷歌技术和前端不是那么深入,所以依靠一棵大树 ABP,没错,鼎鼎大名的广告拦截器,它支持自定义规则的广告拦截,首先下载安装 ABP,安装成功后,点击 ABP 的按钮, 进入下方其 设置 页面,选择 自定义过滤,点击 以纯文本编辑过滤规则,在下方编辑框加上如下规则

new project

##a[class="qd-block"]
##div[class="a_sxfl"]
##.a_sxfl
###location_list
##.uk-header
##.a_sxmu
##.partner-list
##.carousel_container
##.easy-guide
##.bm.a_sxc
##div>span>a
##.bm_c.cl.pbn
##.global_video_bottom_dbtc
##.div-list
###nv
###toptb
###asx_text
##.lt-container2.lt-a-contain
##.bottom
##a_pt
###v_e6_action
###toubiao
###p_btn
##.ad
##.plc.plm
##.pob.cl>p
##.zxy
##.lt-body3
###lt-ad-box
http://img.s8bbs.com/04b22ce33ea24089740dd4c36b3cd7a5.jpg
http://xbluntan.net/plugin-e6-rebate.html
http://static2.keep4u.ru/2017/06/24/230561.jpg

new project

然后点击 确认更改 即可,再次刷新 web 页面就能看到效果了

在这里我要偷一下懒,因为本人真的对 Chrome 和 web 技术并没有深入的研究,只是为了实现功能,况且网上针对 Chrome 扩展的开发教程非常多也很详细,核心理念和苹果的如出一辙,这里我就 po 出完成 css 才注入的 Chrome 插件,相信真心人能看一下就懂了

这个插件能实现功能和上面 Safari 的修改 css 样式的功能一样 http://oqedp1ccg.bkt.clouddn.com/Chrome.crx

安装方法

https://jingyan.baidu.com/article/49ad8bce41a4405834d8fa91.html

好了,再见,广告的世界!

收藏
0
sina weixin mail 回到顶部