利用Google QR Codes API生成二维码名片(二)

  继上一篇文章利用Google QR Codes API生成二维码名片(一)之后,现在终于有时间来继续钻研一下Google API在制作二维码名片中的使用。最原始的需求是这样的,要批量生成二维码名片,故不能用草料二维码等在线二维码生成工具(一个个点,一个个保存太慢了,生成的名片还不好看,爱美之心,人皆有之,要不然别人一扫,就尴尬了)。在上篇文章中我们说了,Google API生成二维码,实质上就是发送一系列参数的请求,返回结果是一个二维码。这时,就有小伙伴发现了,你这还不是一个个发请求,一个个手动保存,而且名片也丑的不忍直视(没有任何的修饰)。接下来,我们来解决这两个关键问题,一、自动下载保存(即可以批量生成), 二、名片太丑啦。

接口回忆

  我们调用Google生成二维码的接口为https://chart.googleapis.com/chart,参数及其含义如下:

1
2
3
4
5
6
cht=qr 必须的参数 指定是一个二维码 例: cht=qr
chs=<width>x<height> 必须的参数 指定图片的大小
chl=<data> 必须的参数 指定内容
choe=<output_encoding> 可选的参数 内容的编码,默认为utf-8,可选的有: UTF-8(默认就是这个), Shift_JIS, ISO-8859-1
chld=<error_correction_level>|<margin> 可选的参数 error_correction_level为错误纠正, L(默认): 允许恢复高达7%的数据丢失 M: 允许回复高达15%的数据丢失 Q: 25% H:30%
margin 数据部分周围的白色边框的宽度,单位是行,不是html中的像素,默认为4

实质上发送一个请求就得到了一个二维码,其中chl参数表示我们在扫码之后的数据(这个二维码扫描后显示”hello世界”):

https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=hello世界&choe=UTF-8&chld=L|4

生成的二维码

自动下载

  仔细想想,我们做下载文件功能时,有时候会用window.open([url]);浏览器会自动帮你下载它。但是但是但是…,当你运行如下的js时:

1
window.open('https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=hello世界&choe=UTF-8&chld=L|4')

  你会发现在新窗口打开了一个页面,页面的内容,不是其他的,正是url返回的二维码图片。至于为什么会这样呢?这和浏览器的渲染引擎有关,默认情况下渲染引擎可以显示HTML,XML以及图片,所以图片直接显示在页面了,在此不深究了(有兴趣的同学可以在网上搜索“浏览器是怎样工作的”去研究研究)。还有一种方法是使用html5的download属性(例:http://www.w3school.com.cn/tiy/t.asp?f=html_a_download),但是这种方式还是需要手动触发点击,那怎么办呢,于是想到我们能不能用代码触发下载呢,答案是当然可以。

  我们运行如下js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var URL = window.URL || window.webkitURL;
var a = document.createElement('a');
var url = 'https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=hello%E4%B8%96%E7%95%8C&choe=UTF-8&chld=L|4';
var filename = 'myqrcode';
a.href = url;
a.download = filename;
if(document.all){ //此处是为了浏览器兼容性
a.click();
}
else{
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
URL.revokeObjectURL(url);

  在chrome中运行,可以自动下载二维码图片(名为chart.png, 而不是我们定义的download属性名)太他娘的不科学了。经过查阅:在Chrome和Opear中,如果说下载文件不是在子集的服务器或域名中,这些浏览器会忽视download属性,换句话来说,文件名不变。于是加上了createObjectURL方法,来生成一个url,不明白此方法的自行到https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL中查看,此处不再啰嗦,我在这里将图片保存为jpg。利用fetch API的写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var URL = window.URL || window.webkitURL;
fetch('https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=hello%E4%B8%96%E7%95%8C&choe=UTF-8&chld=L|4')
.then(
res => res.blob()
.then(blob => {
var a = document.createElement('a');
var url = URL.createObjectURL(blob);
var filename = 'myfile.jpg';
a.href = url;
a.download = filename;
if(document.all){
a.click();
}
else{
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
URL.revokeObjectURL(url);
})
)

相应的,我们亦可以用ajax来实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=hello世界哈哈&choe=UTF-8&chld=L|4', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var a = document.createElement('a');
var url = URL.createObjectURL(blob);
var filename = 'myfile.jpg';
a.href = url;
a.download = filename;
if(document.all){
a.click();
}
else{
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
URL.revokeObjectURL(url);
}
};
xhr.send();

美化名片

  这里介绍两种名片格式VCARD和MECARD。VCARD是*联盟提出的电子名片的格式标准,一般用于商业名片,各个属性之间用’\r\n’分割,MECARD由日本某公司指定的数据格式。下面给出了两种数据格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var data = [
'BEGIN:VCARD', //开头标识
'VERSION:4.0', //版本
'N:123;Forrest;;Mr.', //姓名
'FN:Forrest Gump',
'ORG: 中华人民共和国组织', //组织
'TITLE: 职位', //职位
'PHOTO;GIF: https://nsne.github.io/uploads/avatar.jpg', //照片
'TEL;WORK;VOICE: 工作电话11111', //工作电话
'TEL;HOME;VOICE: 家庭电话2222', //家庭电话
'ADR;WORK;PREF:;;中华人民共和国地球村', //工作地址
'ADR;HOME:;;中华人民共和国', //家庭地址
'EMAIL: 123456798@qq.com', //邮箱
'REV:20160303', //类型定义,指定当前vcard的修改信息
'END:VCARD' //结束标识
].join('\r\n')
var data = ['MECARD:',
'N:姓名', //姓名
'NICKNAME: 昵称',
'TEL: 12345678', //电话
'TEL-AV: 可视电话号码',
'EMAIL:123456789@qq.com', //邮箱
'ADR: 陕西西安', //地址
'URL:https://nsne.github.io', //网址
'NOTE:很好的一个家伙', //备注
'BDAY: 199549848',
].join(';')

  于是乎我们的代码变成了下面这个样子(这里用MECARD演示):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var data = [
'MECARD:',
'N:姓名', //姓名
'NICKNAME: 昵称',
'TEL: 12345678', //电话
'TEL-AV: 可视电话号码',
'EMAIL:123456789@qq.com', //邮箱
'ADR: 陕西西安', //地址
'URL:https://nsne.github.io', //网址
'NOTE:很好的一个家伙', //备注
'BDAY: 1956416',
].join(';')
var URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
var url = 'https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=' + data + '&choe=UTF-8&chld=L|4'
xhr.open('get', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var a = document.createElement('a');
var url = URL.createObjectURL(blob);
var filename = 'myfile.jpg';
a.href = url;
a.download = filename;
if(document.all){
a.click();
}
else{
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
URL.revokeObjectURL(url);
}
};
xhr.send();

  生成二维码以及用微信扫描的结果如下,保存按钮可以将名片信息保存到通讯录:

批量生成

  接下来我们来构建一组数据,生成这组数据的二维码并自动保存到我们的本地磁盘,上code。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//一组数据
var data = [
{
name: '姓名1',
nickName: '昵称1',
tel: '电话1',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名2',
nickName: '昵称2',
tel: '电话2',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名3',
nickName: '昵称3',
tel: '电话3',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名4',
nickName: '昵称4',
tel: '电话4',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名5',
nickName: '昵称5',
tel: '电话5',
email: '425002189@qq.com',
note: 'very nice'
}
];
var URL = window.URL || window.webkitURL;
for(var i = 0; i < data.length; i++) {
var qrdata = [
'MECARD:',
'N:' + data[i].name, //姓名
'NICKNAME: ' + data[i].nickName,
'TEL: ' + data[i].tel, //电话
'EMAIL: ' + data[i].email, //邮箱
'NOTE: ' + data[i].note, //备注
].join(';');
var xhr = new XMLHttpRequest();
var url = 'https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=' + qrdata + '&choe=UTF-8&chld=L|4'
xhr.open('get', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var a = document.createElement('a');
var url = URL.createObjectURL(blob);
var filename = data[i].name + '.jpg'; //以姓名来命名下载的二维码图片名称
a.href = url;
a.download = filename;
if(document.all){
a.click();
}
else{
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
URL.revokeObjectURL(url);
}
};
xhr.send();
}

  你可能以为这样就万事大吉了,其实你错了,与此相关的是js中闭包的概念,此处不赘述,感兴趣错的同学,去网上查看,正确的代码应该是如下这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//一组数据
var data = [
{
name: '姓名1',
nickName: '昵称1',
tel: '电话1',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名2',
nickName: '昵称2',
tel: '电话2',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名3',
nickName: '昵称3',
tel: '电话3',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名4',
nickName: '昵称4',
tel: '电话4',
email: '425002189@qq.com',
note: 'very nice'
},
{
name: '姓名5',
nickName: '昵称5',
tel: '电话5',
email: '425002189@qq.com',
note: 'very nice'
}
];
var URL = window.URL || window.webkitURL;
for(var i = 0; i < data.length; i++) {
(function(i) {
var qrdata = [
'MECARD:',
'N:' + data[i].name, //姓名
'NICKNAME: ' + data[i].nickName,
'TEL: ' + data[i].tel, //电话
'EMAIL: ' + data[i].email, //邮箱
'NOTE: ' + data[i].note, //备注
].join(';');
var xhr = new XMLHttpRequest();
var url = 'https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=' + qrdata + '&choe=UTF-8&chld=L|4'
xhr.open('get', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var a = document.createElement('a');
var url = URL.createObjectURL(blob);
var filename = data[i].name + '.jpg'; //以姓名来命名下载的二维码图片名称
a.href = url;
a.download = filename;
if(document.all){
a.click();
}
else{
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
URL.revokeObjectURL(url);
}
};
xhr.send();
})(i);
}

  到此截止,大功告成,快来制作自己的名片吧。如果您觉得有用,可以点击下方的赏打赏支持我哦。

坚持原创技术分享,您的支持将鼓励我继续创作!