最近由业务需要,需要在之前制作的谷歌扩展(插件)中集成一个验证码自动识别的功能,开发过程中涉及了一些有趣的知识,故在此做一个汇总分享。
本篇主要涉及以下内容:
- 1. 如何将网页中的图片转化为 dataURLs 格式的数据
- 2. 如果绕过 CORF 跨域限制(即在 https 下不能向 http 发送请求)
- 3. 如何在content.js 和 background.js 之间进行通信
## 1. 如何将网页中的图片转化为 dataURLs 格式的数据
为了进行验证码的自动识别,本文使用了网上的收费API接口,该接口需要将图片数据通过 dataURLs 的形式发送过去。这个时候就涉及到一个问题,即如何将网页中的图片转换为 dataURLs。
首先排除使用 img src 的形式,因为发现验证码的 src,每次请求会得到随机不同的验证码图片,这显然是不行的。
尝试了很多方法,最终选用,通过 canvas 进行过渡转换的方式,即:
- 首先将图片加载到 canvas 中
- 然后将 canvas 导出为 dataURLs
代码形式则为:
```js
// 获取图片的 base64信息,并执行回调函数 load_cb
function getImgData(img, load_cb){
var a_canvas = document.createElement('canvas');
var ctx=a_canvas.getContext("2d");
// 此处 img 为通过 document.querySelector 获取的 DOM 对象
ctx.drawImage(img,10,10);
dataURI = a_canvas.toDataURL("image/png");
dataURI = dataURI.split(',');
dataURI = dataURI.pop();
load_cb(dataURI);
}
```
上述代码中首先创建了一个 canvas 2d 对象,然后通过 .drawImage() 在画布中绘制图像(图片来源)
然后将 canvas 将图片转换为 dataURL(base64),即完成了页面上图片向 dataURL (base64) 数据的转化
## 2. 如果绕过 CORF 跨域限制(即在 https 下不能向 http 发送请求)
上面问题解决了,但马上又遇到了新的问题,即 CORF 跨域限制的问题,简单来说也就是在 https 的域名下,不能向 http 的域名发送请求,这个问题比较麻烦,但是在谷歌拓展的情况下很好解决。
首先,通过 content.js 从页面前端获取数据 (dataURL base64),然后将数据通过通信的方式,发送至 background.js ,由于 background.js 可以向任何域发送请求,没有跨域限制,所以完美解决上述问题。
而请求后响应的数据,也可以通过通信的方式,再从 background.js 中传递回来。
## 3. 如何在content.js 和 background.js 之间进行通信
这个问题简单来说就是两段代码:
此处引用了 http://blog.haoji.me/chrome-plugin-develop.html#xiao-xi-tong-xin 的blog。
3.1 content.js 向 background.js 发送数据
content-script.js
```js
chrome.runtime.sendMessage({greeting: '你好,我是content-script呀,我主动发消息给后台!'}, function(response) {
console.log('收到来自后台的回复:' + response);
});
```
background.js
```js
// 监听来自content-script的消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
console.log('收到来自content-script的消息:');
console.log(request, sender, sendResponse);
sendResponse('我是后台,我已收到你的消息:' + JSON.stringify(request));
});
```
3.2 background.js 向 content.js 发送数据
background.js
```js
function sendMessageToContentScript(message, callback)
{
chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
{
chrome.tabs.sendMessage(tabs[0].id, message, function(response)
{
if(callback) callback(response);
});
});
}
sendMessageToContentScript({cmd:'test', value:'你好,我是popup!'}, function(response)
{
console.log('来自content的回复:'+response);
});
```
content-script.js
```js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
// console.log(sender.tab ?"from a content script:" + sender.tab.url :"from the extension");
if(request.cmd == 'test') alert(request.value);
sendResponse('我收到了你的消息!');
});
```
网友评论