火狐插件油猴Greasemonkey系列一

油猴Greasemonkey是火狐浏览器user script插件,类似于浏览器端的页面拦截器,对于补充修改增强遗留系统功能有不错的效果。缺点在于插件是安装在浏览器端,部署不是很方便,所以只能是个小众软件。

本系列主要测试油猴插件引用jQuery库的操作。火狐版本25.0,油猴插件版本1.15.1-signed。

引入的两个测试jQuery版本为:页面版本2.2.1,插件版本1.12.1。

新建web项目,测试页面page.html,位于上下文的根部,用户脚本为test.user.js,位于userscripts目录下。

文件结构如图:


 

测试情形1:page.html没有引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:

page.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游猴插件测试页面</title>
</head>
<body>
	<div id="container">
		<button onclick="alert('page button click event:' + $.fn.jquery)">content button</button>
	</div>
	<div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div>
</body>
</html>

 test.user.js

// ==UserScript==
// @name        test
// @namespace   http://yc.telecomjs.com/gm
// @description 油猴jQuery库测试
// @include     http://localhost:8080/gm/page.html
// @require		http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js
// @grant none
// @version     1.0
// ==/UserScript==

console.log($.fn.jquery);

$('#container').append('<button id="script_btn">script button</button>');

$('#script_btn').click(function(){
	alert('script button click event');
});

 经过firebug查看控制台,jQuery版本号能够正确显示,扩充的按钮能够正常显示,单击事件正常,点击页面按钮,显示:page button click event:1.12.1,说明用户脚本的库入侵了页面,要避免这样使用jQuery。

测试情形2:page.html没有引入jquery,元数据@grant unsafeWindow,此时用户脚本运行于沙盒中:

修改 test.user.js中的@grant none为@grant unsafeWindow,测试正常。

测试情形3:page.html中引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:

 page.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游猴插件测试页面</title>
<script type="text/javascript" src="libs/jquery/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
	console.log('page jquery:' + $.fn.jquery);
	$(function(){
		$('#page_btn').click(function(){
			alert('page button click event:' + $.fn.jquery);
		});
	});
</script>
</head>
<body>
	<div id="container">
		<button id="page_btn">content button</button>
	</div>
	<div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div>
</body>
</html>

  test.user.js
// ==UserScript==
// @name        test
// @namespace   http://yc.telecomjs.com/gm
// @description 油猴jQuery库测试
// @include     http://localhost:8080/gm/page.html
// @require		http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js
// @grant none
// @version     1.2
// ==/UserScript==

console.log('user script jquery:' + $.fn.jquery);

$('#container').append('<button id="script_btn">script button</button>');

$('#script_btn').click(function(){
	alert('script button click event:' + $.fn.jquery);
});
 
经过测试:
console输出:
page jquery:2.2.1
user script jquery:1.12.1
点击content button,输出:page button click event:1.12.1
点击script button,输出:script button click event:1.12.1
这个测试结果说明:用户脚本在页面所有脚本执行完成后执行,所以console的jQuery版本是2.2.1,脚本引入jQuery会替换页面的jQuery,原因在于jQuery中有将$和jQuery赋值给window.$ 和 window.jQuery的操作,@grant none的情形下,window等于unsafeWindow,脚本的jQuery就替代了页面jQuery,在不同版本下的jQuery,有可能会导致页面原始功能异常,所以要特别小心,下面是两种安全的情形。
 
测试情形4:page.html引入jquery,元数据@grant unsafeWindow,此时用户脚本运行于沙盒中:
将情形3中的@grant none修改为@grant unsafeWindow
此时测试结果:
console输出:
page jquery:2.2.1
user script jquery:1.12.1
点击content button,输出:page button click event:2.2.1
点击script button,输出:script button click event:1.12.1
用户脚本运行在沙盒里面,没有与页面js冲突,可以解决情形3的问题。
 
测试情形5:page.html中引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:
修改情形3的 test.user.js的文件为:
// ==UserScript==
// @name        test
// @namespace   http://yc.telecomjs.com/gm
// @description 油猴jQuery库测试
// @include     http://localhost:8080/gm/page.html
// @require		http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js
// @grant none
// @version     1.5
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
console.log('user script jquery:' + $.fn.jquery);

$('#container').append('<button id="script_btn">script button</button>');

$('#script_btn').click(function(){
	alert('script button click event:' + $.fn.jquery);
});
测试结果同情形4,说明this.$ = this.jQuery = jQuery.noConflict(true);将页面的jQuery版本做了复原。
 
测试情形6:page.html中未引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中:
page.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游猴插件测试页面</title>
</head>
<body>
	<div id="container">
		<button onclick="alert('page button click event:' + $)">content button</button>
	</div>
	<div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div>
</body>
</html>
 
test.user.js
// ==UserScript==
// @name        test
// @namespace   http://yc.telecomjs.com/gm
// @description 油猴jQuery库测试
// @include     http://localhost:8080/gm/page.html
// @require		http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js
// @grant none
// @version     1.6
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
console.log('user script jquery:' + $.fn.jquery);

$('#container').append('<button id="script_btn">script button</button>');

$('#script_btn').click(function(){
	alert('script button click event:' + $.fn.jquery);
});
console输出:
user script jquery:1.12.1
点击content button,输出:page button click event:undefined
点击script button,输出:script button click event:1.12.1
结果是正常的。
 
总结,在油猴用户脚本中引入jQuery库,最好运行在沙盒环境下,简单地加一条元数据@grant unsafeWindow即可;如果运行在@grant none情形下,在脚本的顶部一定要添加一条this.$ = this.jQuery = jQuery.noConflict(true);以防止与原页面jQuery库冲突,导致原页面功能异常。
 
系统二准备测试下用户脚本如何引入bootstrap的css文件方案。
经过测试: console输出: page jquery:2.2.1 user script jquery:1.12.1 点击content button,输出:page button click event:1.12.1 点击script button,输出:script button click event:1.12.1 这个测试结果说明:用户脚本在页面所有脚本执行完成后执行,所以console的jQuery版本是2.2.1,脚本引入jQuery会替换页面的jQuery,原因在于jQuery中有将$和jQuery赋值给window.$ 和 window.jQuery的操作,@grant none的情形下,window等于unsafeWindow,脚本的jQuery就替代了页面jQuery,在不同版本下的jQuery,有可能会导致页面原始功能异常,所以要特别小心,下面是两种安全的情形。   测试情形4:page.html引入jquery,元数据@grant unsafeWindow,此时用户脚本运行于沙盒中: 将情形3中的@grant none修改为@grant unsafeWindow 此时测试结果: console输出: page jquery:2.2.1 user script jquery:1.12.1 点击content button,输出:page button click event:2.2.1 点击script button,输出:script button click event:1.12.1 用户脚本运行在沙盒里面,没有与页面js冲突,可以解决情形3的问题。   测试情形5:page.html中引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中: 修改情形3的 test.user.js的文件为:
// ==UserScript==
// @name        test
// @namespace   http://yc.telecomjs.com/gm
// @description 油猴jQuery库测试
// @include     http://localhost:8080/gm/page.html
// @require		http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js
// @grant none
// @version     1.5
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
console.log('user script jquery:' + $.fn.jquery);

$('#container').append('<button id="script_btn">script button</button>');

$('#script_btn').click(function(){
	alert('script button click event:' + $.fn.jquery);
});
测试结果同情形4,说明this.$ = this.jQuery = jQuery.noConflict(true);将页面的jQuery版本做了复原。   测试情形6:page.html中未引入jquery,元数据@grant none,此时用户脚本运行在非特权无沙盒中: page.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游猴插件测试页面</title>
</head>
<body>
	<div id="container">
		<button onclick="alert('page button click event:' + $)">content button</button>
	</div>
	<div id="install"><a href="userscripts/test.user.js">用户脚本安装</a></div>
</body>
</html>
  test.user.js
// ==UserScript==
// @name        test
// @namespace   http://yc.telecomjs.com/gm
// @description 油猴jQuery库测试
// @include     http://localhost:8080/gm/page.html
// @require		http://localhost:8080/gm/libs/jquery/jquery-1.12.1.min.js
// @grant none
// @version     1.6
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
console.log('user script jquery:' + $.fn.jquery);

$('#container').append('<button id="script_btn">script button</button>');

$('#script_btn').click(function(){
	alert('script button click event:' + $.fn.jquery);
});
console输出: user script jquery:1.12.1 点击content button,输出:page button click event:undefined 点击script button,输出:script button click event:1.12.1 结果是正常的。   总结,在油猴用户脚本中引入jQuery库,最好运行在沙盒环境下,简单地加一条元数据@grant unsafeWindow即可;如果运行在@grant none情形下,在脚本的顶部一定要添加一条this.$ = this.jQuery = jQuery.noConflict(true);以防止与原页面jQuery库冲突,导致原页面功能异常。   系统二准备测试下用户脚本如何引入bootstrap的css文件方案。

猜你喜欢

转载自nalan.iteye.com/blog/2281223
今日推荐