昨天网上冲浪看了下chrome开发文档,写个翻译小插件练手,平时看外文文档查点生词还是挺方便的。
该插件实现主要思路很简单,将content.js注入脚本进入浏览页面,利用window.getSelection()
方法获取当前页面被鼠标选取的文字,之后利用chrome的api chrome.extension.sendRequest
将之前获取的字符传给background,之后background中ajax调用翻译接口获取翻译结果后,利用chrome.storage.local
存储后,在popup页面中进行显示。
为了方便直接使用popup进行结果的输出,也可以写一个悬浮框方便结果实时显示,将background中的结果传回content就行。
效果展示
百度翻译响应还是很快的。
Content.js在插件中用来向当前页面注入脚本或者css样式。本文实现的插件选了对github以及其子链接有效,在插件manifest清单文件中写入content文件:
"content_scripts": [
{
"matches": ["https://github.com/*"],
"js": ["jquery.js", "md5.js", "content.js"]
}
],
为了演示下,这里设置只有在github相关页面中才执行脚本注入,同时指定注入的js文件。
具体逻辑在content.js文件中实现:
var now = "begin select"
$(document).ready(function(){
$("div").on("click", selectTrans)
})
function selectTrans(){
var text = getSelect()
var textStr = text.toString()
// 防止因为div太多多次调用
if(textStr != now && textStr!=""){
console.log(text.toString())
now = textStr
sendRequestToPopup(textStr)
}
}
function getSelect(){
var text = window.getSelection()
if(text == null){
return "blank"
}
return text
}
代码首先对所有的div块设置一个click的回调函数,这样无论页面上哪些文字被选中都能被获取到。
在getSelect()函数中,利用window.getSelection()获取选中信息,要获取文本的话,需要调用其toString()方法,将字符串获取。为了防止div太多,点到别处时会获取空字符串或重复字符串,在selectTrans函数中进行判断,判断成功后传递信息。
function sendRequestToPopup(textStr){
chrome.extension.sendRequest({'text': textStr}, function(response){
console.log(response); // 将返回信息打印到控制台里
});
}
调用chrome.extension库中的sendRequest方法,将包含数据的对象传递出去,同时设置回调函数,将返回信息在控制台中输出。该方法可同时将request传递给popup和background,只要它们接收即可。
因为content security policy(CPS)安全性的规定,不能在https的页面中执行对于http的访问,所以利用content传递数据,在background中进行ajax的接口访问。
Manifest中设置background的脚本文件,这边只需要进行后台数据处理,所以不用html文件:
"background":{
"scripts": ["jquery.js", "md5.js", "background.js"]
},
首先是利用onRequest监听传送过来的数据,处理完后存储到chrome的local中:
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
textNow = request.text
sendResponse("send success:" + textNow);
console.log(textNow)
trans(textNow)
// afterTrans = textNow
chrome.storage.local.set(
{
former_result: textNow,
translate_result: afterTrans
},function(){
console.log("store result:"+afterTrans)
}
)
}
)
其中trans函数调用了ajax进行翻译信息获取,翻译接口使用的是百度翻译,返回一个对象信息,处理下获取翻译结果就行了。调用接口需要对应应用的id和key,开发者平台申请即可。
function trans(text){
// 调用百度翻译接口
var query = text.toString()
var from = "auto"
var to = "zh"
var appid = "xxx" //你的id
var key = "xxx" //你的key
var salt = (new Date).getTime()//取当前时间作为随机数
var str1 = appid + query + salt + key
var md5_str = MD5(str1)
$.ajax({
url: 'http://api.fanyi.baidu.com/api/trans/vip/translate',
type: 'get',
dataType: 'json',
data:{
appid: appid,
q: query,
from: from,
to: to,
salt: salt,
sign: md5_str
},
success: function(result){
console.log(result)
var res = getTranslateResult(result)
afterTrans = res
console.log(res)
// setResult(res)
}
})
}
MD5文件是百度翻译demo里面拿来的,直接用就行。
需要注意的是,chrome插件不支持jsonp格式信息的获取,百度翻译示范中ajax的dataType是jsonp,这边修改为json。不然会违反csp规定,报错是:because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
Popup属于browser action的组件,因为失去焦点就会关闭页面,所以选择下一个词之后会重新加载,这时候读取对应数据显示就行了。
Manifest:
"browser_action": {
"default_icon": "images/t.png",
"default_title": "translate tool",
"default_popup": "test.html"
},
需要注意的是,chrome插件为了安全起见,不会调用popup页面中直接使用
<link href="pop.css" type="text/css" rel="stylesheet" />
<script src="jquery.js"></script>
<script src="md5.js"></script>
<script src="popup.js"></script>
Popup.js:
$(document).ready(function(){
chrome.storage.local.get("translate_result",function(result){
$("#translate_result").text(result['translate_result'])
$(".main_screen")
})
chrome.storage.local.get("former_result",function(result){
$("#former_result").text(result['former_result'])
})
})
简单在加载完毕后显示对应值即可。
看了下文档简单调用下接口熟悉了下插件,实现也比较简单,要继续做美化可以利用content的css注入来实现一个悬浮框。能注入脚本到当前页面还挺不错的,可以用来爬虫,修改页面样式等。不过因为csp的关系,很多时候要注意安全的写法,也确实需要注意安全,毕竟能直接注入脚本,不要用来历不明的插件哈。
项目已传github:https://github.com/huiluczP/translate_plug_in
因篇幅问题不能全部显示,请点此查看更多更全内容