antstrong's corner

Live beautiful


  • 首页

  • 分类

  • 标签

  • 成就

  • 搜索
close
antstrong's corner

深入理解JSON

发表于 2017-05-01 | 分类于 json | | 阅读次数

深入理解JSON

如果你愿意一层一层剥开我的心,你会发现…这里水很深——深入理解JSON

我们先来看一个JS中常见的JS对象序列化成JSON字符串的问题,请问,以下JS对象通过JSON.stringify后的字符串是怎样的?先不要急着复制粘贴到控制台,先自己打开一个代码编辑器或者纸,写写看,写完再去仔细对比你的控制台输出,如果有误或者需要一段时间去考量,那么这次分享就有意义了

1
2
3
4
5
6
7
8
9
10
11
var friend = {
firstName: 'Good',
'lastName': 'Man',
'address': undefined,
'phone': ["1234567",undefined],
'fullName': function(){
return this.firstName + ' ' + this.lastName;
}
};
JSON.stringify(friend); //这一行返回什么呢?

第二个问题,如果我想在最终JSON字符串将这个’friend’的姓名全部变成大写字母,也就是把”Good”变成”GOOD”,把”Man”变成”MAN”,那么可以怎么做?

基于以上两个问题,我们再追本溯源问一下,JSON究竟是什么东西?为什么JSON就易于数据交换了呢?JSON和JS对象有什么区别?JS中JSON.parse、JSON.stringify和不常见的toJSON,这几个函数的参数和处理细节到底是怎样的?

欢迎进入本次“深挖JSON之旅”,下文将从以下几个方面去理解JSON:

  • 首先是对“JSON是一种轻量的数据交换格式”的理解;
  • 然后来看经常被混为一谈的JSON和JS对象的区别;
  • 最后我们再来看JS中这几个JSON相关函数具体的执行细节。

希望这次分享能让大家如之前的我一样对JSON从一知半解到能说清楚JSON是什么,也能熟练运用JSON,不看控制台就知道JS对象序列化成JSON字符串后输出是啥。

一、JSON是一种格式,基于文本,优于轻量,用于交换数据

如果没有去过JSON的官方介绍可以去一下这里,官方介绍第一、二段已经很清楚地表述了JSON是什么,我将JSON是什么提炼成以下几个方面:

1. 一种数据格式

什么是格式?就是规范你的数据要怎么表示,举个栗子,有个人叫“二百六”,身高“160cm”,体重“60kg”,现在你要将这个人的这些信息传给别人或者别的什么东西,你有很多种选择:

  • 姓名“二百六”,身高“160cm”,体重“60kg”
  • name=”二百六”&height=”160cm”&weight=”60kg”
  • {“name”:”二百六”,”height”:160,”weight”:60}
  • … …

以上所有选择,传递的数据是一样的,但是你可以看到形式是可以各式各样的,这就是各种不同格式化后的数据,JSON是其中一种表示方式

2. 基于文本的数据格式

JSON是基于文本的数据格式,相对于基于二进制的数据,所以JSON在传递的时候是传递符合JSON这种格式(至于JSON的格式是什么我们第二部分再说)的字符串,我们常会称为“JSON字符串”。

3. 轻量级的数据格式

在JSON之前,有一个数据格式叫xml,现在还是广泛在用,但是JSON更加轻量,如xml需要用到很多标签,像上面的例子中,你可以明显看到xml格式的数据中标签本身占据了很多空间,而JSON比较轻量,即相同数据,以JSON的格式占据的带宽更小,这在有大量数据请求和传递的情况下是有明显优势的

4. 被广泛地用于数据交换

轻量已经是一个用于数据交换的优势了,但更重要的JSON是易于阅读、编写和机器解析的,即这个JSON对人和机器都是友好的,而且又轻,独立于语言(因为是基于文本的),所以JSON被广泛用于数据交换。

以前端JS进行ajax的POST请求为例,后端PHP处理请求为例:

  1. 前端构造一个JS对象,用于包装要传递的数据,然后将JS对象转化为JSON字符串,再发送请求到后端;
  2. 后端PHP接收到这个JSON字符串,将JSON字符串转化为PHP对象,然后处理请求。

可以看到,相同的数据在这里有3种不同的表现形式,分别是前端的JS对象、传输的JSON字符串、后端的PHP对象,JS对象和PHP对象明显不是一个东西,但是由于大家用的都是JSON来传递数据,大家都能理解这种数据格式,都能把JSON这种数据格式很容易地转化为自己能理解的数据结构,这就方便啦,在其他各种语言环境中交换数据都是如此。

二、JSON和JS对象之间的“八卦”

很多时候都听到“JSON是JS的一个子集”这句话,而且这句话我曾经也一直这么认为,每个符合JSON格式的字符串你解析成js都是可以的,直到后来发现了一个奇奇怪怪的东西…

1. 两个本质不同的东西为什么那么密切

JSON和JS对象本质上完全不是同一个东西,就像“斑马线”和“斑马”,“斑马线”基于“斑马”身上的条纹来呈现和命名,但是斑马是活的,斑马线是非生物。

同样,”JSON”全名”JavaScript Object Notation”,所以它的格式(语法)是基于JS的,但它就是一种格式,而JS对象是一个实例,是存在于内存的一个东西。

此外,JSON是可以传输的,因为它是文本格式,但是JS对象是没办法传输的,在语法上,JSON也会更加严格,但是JS对象就很松了。

那么两个不同的东西为什么那么密切,因为JSON毕竟是从JS中演变出来的,语法相近。

2. JSON格式比JS对象语法表现上严格在哪

现就以“键值对为表现的对象”形式,对比下两者的不同,至于JSON还能以怎样的形式表现,对比完后再罗列。

对比内容 JSON JS对象
键名 必须是加双引号 可允许不加、加单引号、加双引号
属性值 只能是数值(10进制)、字符串(双引号)、布尔值和null,也可以是数组或者符合JSON要求的对象,不能是函数、NaN, Infinity, -Infinity和undefined 爱啥啥
逗号问题 最后一个属性后面不能有逗号 可以
数值 前导0不能用,小数点后必须有数字 没限制

可以看到,相对于JS对象,JSON的格式更严格,所以大部分时候我们写的JS对象是不符合JSON的格式的(至少我是)。

代码对比

1
var obj1 = {}; // 这只是 JS 对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 可把这个称做:JSON 格式的 JavaScript 对象
var obj2 = {"width":100,"height":200,"name":"rose"};
// 可把这个称做:JSON 格式的字符串
var str1 = '{"width":100,"height":200,"name":"rose"}';
// 这个可叫 JSON 格式的数组,是 JSON 的稍复杂一点的形式
var arr = [
{"width":100,"height":200,"name":"rose"},
{"width":100,"height":200,"name":"rose"},
{"width":100,"height":200,"name":"rose"},
];
// 这个可叫稍复杂一点的 JSON 格式的字符串
var str2='['+
'{"width":100,"height":200,"name":"rose"},'+
'{"width":100,"height":200,"name":"rose"},'+
'{"width":100,"height":200,"name":"rose"},'+
']';

另外,除了常见的“正常的”JSON格式,要么表现为一个对象形式{…},要么表现为一个数组形式[…],任何单独的一个10进制数值、双引号字符串、布尔值和null都是有效符合JSON格式的。

这里有完整的JSON语法参考

3. 一个有意思的地方,JSON不是JS的子集

首先看下面的代码,你可以copy到控制台执行下:

1
2
3
var code = '"\u2028\u2029"';
JSON.parse(code); // works fine
eval(code); // fails

这两个字符\u2028和\u2029分别表示行分隔符和段落分隔符,JSON.parse可以正常解析,但是当做js解析时会报错。

三、这几个JS中的JSON函数

在JS中我们主要会接触到两个和JSON相关的函数,分别用于JSON字符串和JS数据结构之间的转化,一个叫JSON.stringify,它很聪明,聪明到你写的不符合JSON格式的JS对象都能帮你处理成符合JSON格式的字符串,所以你得知道它到底干了什么,免得它只是自作聪明,然后让你Debug long time;另一个叫JSON.parse,用于转化json字符串到JS数据结构,它很严格,你的JSON字符串如果构造地不对,是没办法解析的。

它们的参数不止一个,虽然我们经常用的时候只传入一个参数。

此外,还有一个toJSON函数,我们较少看到,但是它会影响JSON.stringify。

1. 将JS数据结构转化为JSON字符串——JSON.stringify

这个函数的函数签名是这样的:

1
JSON.stringify(value[, replacer [, space]])

下面将分别展开带1~3个参数的用法,最后是它在序列化时做的一些“聪明”的事,要特别注意。

1.1 基本使用——仅需一个参数

这个大家都会使用,传入一个JSON格式的JS对象或者数组,JSON.stringify({“name”:”Good Man”,”age”:18})返回一个字符串’{“name”:”Good Man”,”age”:18}’。

可以看到本身我们传入的这个JS对象就是符合JSON格式的,用的双引号,也没有JSON不接受的属性值,那么如果像开头那个例子中的一样,how to play?不急,我们先举简单的例子来说明这个函数的几个参数的意义,再来说这个问题。

1.2 第二个参数可以是函数,也可以是一个数组
  • 如果第二个参数是一个函数,那么序列化过程中的每个属性都会被这个函数转化和处理
  • 如果第二个参数是一个数组,那么只有包含在这个数组中的属性才会被序列化到最终的JSON字符串中
  • 如果第二个参数是null,那作用上和空着没啥区别,但是不想设置第二个参数,只是想设置第三个参数的时候,就可以设置第二个参数为null

这第二个参数若是函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":"1234567",
"age":18
};
var friendAfter=JSON.stringify(friend,function(key,value){
if(key==="phone")
return "(000)"+value;
else if(typeof value === "number")
return value + 10;
else
return value; //如果你把这个else分句删除,那么结果会是undefined
});
console.log(friendAfter);
//输出:{"firstName":"Good","lastName":"Man","phone":"(000)1234567","age":28}

如果制定了第二个参数是函数,那么这个函数必须对每一项都有返回,这个函数接受两个参数,一个键名,一个是属性值,函数必须针对每一个原来的属性值都要有新属性值的返回。

那么问题来了,如果传入的不是键值对的对象形式,而是方括号的数组形式呢?,比如上面的friend变成这样:friend=[“Jack”,”Rose”],那么这个逐属性处理的函数接收到的key和value又是什么?如果是数组形式,那么key是索引,而value是这个数组项,你可以在控制台在这个函数内部打印出来这个key和value验证。

这第二个参数若是数组

1
2
3
4
5
6
7
8
9
10
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":"1234567",
"age":18
};
var friendAfter=JSON.stringify(friend,["firstName","address","phone"]);
console.log(friendAfter);

如果第二个参数是一个数组,那么只有在数组中出现的属性才会被序列化进结果字符串,只要在这个提供的数组中找不到的属性就不会被包含进去,而这个数组中存在但是源JS对象中不存在的属性会被忽略,不会报错。

1.3 第三个参数用于美化输出——不建议用

指定缩进用的空白字符,可以取以下几个值

  • 是1-10的某个数字,代表用几个白字符
  • 是字符串的话,就用该字符串代替空格,最多取这个字符串的前10个字符
  • 没有提供该参数 等于 设置成null 等于 设置一个小于1的数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":{"home":"1234567","work":"7654321"}
};
//直接转化毫无疑问是这样的:
//{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":"7654321"}}
var friendAfter=JSON.stringify(friend,null,4);
console.log(friendAfter);
// ?
var friendAfter=JSON.stringify(friend,null,"HAHAHAHA");
console.log(friendAfter);
// ?
var friendAfter=JSON.stringify(friend,null,"WhatAreYouDoingNow");
console.log(friendAfter);
// ?

知道用法就好,但千万别这样用,序列化是为了传输,传输就是能越小越好,加莫名其妙的缩进符,解析困难(如果是字符串的话),也弱化了轻量化这个特点。

1.4 注意这个函数的“小聪明”(重要)

如果有其他不确定的情况,那么最好的办法就是”Have a try”,控制台做下实验就明了。

  • 键名不是双引号的(包括没有引号或者是单引号),会自动变成双引号;字符串是单引号的,会自动变成双引号
  • 最后一个属性后面有逗号的,会被自动去掉
  • 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中这个好理解,也就是对非数组对象在最终字符串中不保证属性顺序和原来一致
  • 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值也就是你的什么new String(“bala”)会变成”bala”,new Number(2017)会变成2017
  • undefined、任意的函数(其实有个函数会发生神奇的事,后面会说)以及 symbol 值(symbol详见ES6对symbol的介绍

    • 出现在非数组对象的属性值中:在序列化过程中会被忽略
    • 出现在数组中时:被转换成 null
      1
      2
      JSON.stringify({x: undefined, y: function(){return 1;}, z: Symbol("")});
      JSON.stringify([undefined, Object, Symbol("")]);
  • NaN、Infinity和-Infinity,不论在数组还是非数组的对象中,都被转化为null

  • 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们
  • 不可枚举的属性会被忽略

2. 将JSON字符串解析为JS数据结构——JSON.parse

这个函数的函数签名是这样的:

1
JSON.parse(text[, reviver])

如果第一个参数,即JSON字符串不是合法的字符串的话,那么这个函数会抛出错误,所以如果你在写一个后端返回JSON字符串的脚本,最好调用语言本身的JSON字符串相关序列化函数,而如果是自己去拼接实现的序列化字符串,那么就尤其要注意序列化后的字符串是否是合法的,合法指这个JSON字符串完全符合JSON要求的严格格式。

值得注意的是这里有一个可选的第二个参数,这个参数必须是一个函数,这个函数作用在属性已经被解析但是还没返回前,将属性处理后再返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":{"home":"1234567","work":["7654321","999000"]}
};
//我们先将其序列化
var friendAfter=JSON.stringify(friend);
//'{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":["7654321","999000"]}}'
//再将其解析出来,在第二个参数的函数中打印出key和value
JSON.parse(friendAfter,function(k,v){
console.log(k);
console.log(v);
console.log("----");
});

仔细看一下这些输出,可以发现这个遍历是由内而外的,可能由内而外这个词大家会误解,最里层是内部数组里的两个值啊,但是输出是从第一个属性开始的,怎么就是由内而外的呢?

这个由内而外指的是对于复合属性来说的,通俗地讲,遍历的时候,从头到尾进行遍历,如果是简单属性值(数值、字符串、布尔值和null),那么直接遍历完成,如果是遇到属性值是对象或者数组形式的,那么暂停,先遍历这个子JSON,而遍历的原则也是一样的,等这个复合属性遍历完成,那么再完成对这个属性的遍历返回。本质上,这就是一个深度优先的遍历。

有两点需要注意:

  • 如果 reviver 返回 undefined,则当前属性会从所属对象中删除,如果返回了其他值,则返回的值会成为当前属性新的属性值。
  • 你可以注意到上面例子最后一组输出看上去没有key,其实这个key是一个空字符串,而最后的object是最后解析完成对象,因为到了最上层,已经没有真正的属性了

3. 影响 JSON.stringify 的神奇函数——object.toJSON

如果你在一个JS对象上实现了toJSON方法,那么调用JSON.stringify去序列化这个JS对象时,JSON.stringify会把这个对象的toJSON方法返回的值作为参数去进行序列化。

1
2
3
4
5
6
7
8
9
10
var info={
"msg":"I Love You",
"toJSON":function(){
var replaceMsg=new Object();
replaceMsg["msg"]="Go Die";
return replaceMsg;
}
};
JSON.stringify(info);

这个函数就是这样子的。

其实Date类型可以直接传给JSON.stringify做参数,其中的道理就是,Date类型内置了toJSON方法。

四、小结以及关于兼容性的问题

到这里终于把JSON和JS中的JSON,梳理了一遍,也对里面的细节和注意点进行了一次遍历,知道JSON是一种语法上衍生于JS语言的一种轻量级的数据交换格式,也明白了JSON相对于一般的JS数据结构(尤其是对象)的差别,更进一步,仔细地讨论了JS中关于JSON处理的3个函数和细节。

原文地址

antstrong's corner

工作中常用的几种jsonp处理跨域的方式

发表于 2017-04-07 | 分类于 js | | 阅读次数

工作中常用的几种jsonp处理跨域的方式

一.用jQuery的ajax方法

先上代码

1
2
3
4
5
6
7
$.ajax({
url: 'url',
data: {},
type: 'get',
dataType: "jsonp",
jsonp: 'callback',
})

其中的三个关键参数是

  1. type:请求方法,由于是跨域请求,所以肯定是get;
  2. dataType:一般我们这个参数的值都是json,但是由于这里用jsonp处理跨域,所以参数是’jsonp’;
  3. jsonp: 这个参数最为重要,这个值是我们本地定义的一个函数,当用jsonp处理跨域时,会把这个函数带到后端,然后后端用此函数将实际返回的数据用callback包装起来返回给我们(自己的浅显理解)。
    这里有个坑需要特别强调下
    通常情况下我们的请求是通过按钮触发的,这时候我们就有了如下的代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $('#btn').on('click', function () {
    $.ajax({
    url: '',
    data: {},
    type: 'get',
    async: false,
    dataType: "jsonp",
    jsonp: 'callback',
    })
    function callback(res) {
    if (res.errno === 0) {
    pop_show();
    $('#success').show();
    } else if (res.errno === -26) {
    pop_show();
    $('#fail').show();
    } else {
    alert(res.desc)
    }
    }

如上,打开控制台,如果后台没有问题会报callback not defined,这时候我们必须加上window.callback = callback以解决此问题。

二.用jQuery的$.getJSON方法

1
$.getJSON('http://user.tvesou.com/wechat/get_jssdk_sign?app=1&url=' + encodeURIComponent(location.href.split('#')[0]) + '&callback=?',function(res){})

运用jQuery的$.getJSON这种方法跨域更为简单,在请求的第一个参数也即是url后面带上需要传递的参数,最后必须带上&callback=?,后面的一个参数则是请求成功后的回调函数。其实这中方法的关键就是在url后面带上&callback=?啦,其他的参数和正常情况下完全一样。

三.最后一种就是利用vue-resource

下面是我平时封装的一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function cpost(v, cdata) {
let nwtime = getNowTime() //时间
let sign = getSign(nwtime) //时间加固定字符串生成的md5
let param = {
nwtime: nwtime,
sign: sign
}
let HOST = '固定url' + cdata.url
for (let key in cdata.postData) {
param[key] = cdata.postData[key]
}
v.$http.jsonp(HOST, {params: param})
.then(response => {
response = response.body
cdata.callback(response)
}, response => {
console.log('网络错误!')
})
}

其实这种方法vue-resource的jsonp和jQuery的 $.getJSON差不多,就不多说了,这里想说明的是vue-resource中的一个坑(其实也不算坑,是自己文档没有看仔细),记得最开始接触的折腾了很久,这个需要注意的点就是,在vue-resource中我们传递给后端的参数都必须这样进行封装:{params: ’我们自己的参数‘},也即是我们传递给vue-resource的是一个对象,params属性是固定的,后面的值就是要传递的参数。

antstrong's corner

两个移动端样式记录

发表于 2017-03-07 | 分类于 css | | 阅读次数
  1. 移动端底部内容区域超过屏幕高度,有蒙层的情况下底部仍可滑动

    默认情况下html, body元素的overflow属性均为auto,因此当有蒙层的情况下需要将前面两个元素的overflow设置为hidden,当去掉蒙层的时候需要重新设置overflow属性的值为auto以确保页面的正常,下面为两个实现此功能的函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //为了防止蒙层底部页面滑动。注:必须对html和body都设置overflow:hidden,移动端才能禁止蒙层底部页面滑动
    function pop_show() {
    $('html').attr("style", "overflow:hidden;height:100%;");
    $('body').attr("style", "overflow:hidden;height:100%;");
    }
    //蒙层关闭时body和html的overflow还原;
    function pop_close() {
    $('html').attr("style", "overflow:auto;");
    $('body').attr("style", "overflow:auto;");
    }

    ​

  2. text-indent属性

    text-indent定义:text-indent 属性 规定了 一个元素 首行 文本内容之前应该有多少水平空格。Horizontal spacing is with respect to the left (or right, for right-to-left layout) edge of the containing block element’s box.

    当text-indent的值设置为数字时,单位是肯定有的(这里有个梗:开始我自己的记忆深处这个属性一直是有单位的,但是当我请教别人时,他觉得没有单位,当时由于没仔细观察没应用单位时确实去掉了我当时的bug,不过原因是不带单位这个属性根本不起作用啊,有木有),要么是em要么是px要么是百分比(此时相对于父元素的宽度)。

    案例:

    如上图,右边的胜负平的图片,这里我的实现是用图片作为背景,然后将字体应用text-indent以实现隐藏

    1
    2
    3
    <div class="narrow f_l"><span
    :class="{vector: item.result==='胜',lose: item.result==='负',draw: item.result==='平'}">{{item.result}}</span>
    </div>

    这里针对不同的结果,应用不同的背景图片,css如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .vector, .lose, .unknow, .draw
    display inline-block
    width 28px
    height 13px
    line-height 13px
    transform skew(-30deg) /*设置倾斜度为-30*/
    color #FFF
    text-align center
    text-indent 2000px

    注意上面css中的第一行,可以算是text-indent的又一个特性,其适用的元素是block containers,对行内元素没有任何作用

    ​ 这时的效果在chrome下的模拟器中表现的一切都正常,但是当你在手机端去查看的时候会发现,屏幕居然可以左右滑动,为什么呢?当我把所有的项目的所有css都看了一遍之后也没发现个所以然,最后请教大神才发现问题所在,但是大神开始一眼看出是text-indent多了单位,当把px去掉之后,左右可滑动的bug确实解决了,但是后面我仔细观察才发现原来字并没有缩进,而是和背景图重合在了一起,后面查阅资料才发现text-indent的如上知识点。因为原来的记忆中貌似text-indent一般都设置为-999px,果然当做了如上修改后,一切都恢复正常:文字被缩进到屏幕之外,左右也没有了滑动效果。

  3. 总结:所以,细节决定成败,看似很基础的知识,很渺小的问题往往会起决定性的作用。

    ​

antstrong's corner

hexo博客next主题折腾记

发表于 2016-12-22 | 分类于 折腾 | | 阅读次数

首先,我很清楚现在网络上关于用hexo搭建博客的文章已经不计其数,但是在自己搭建完本博客之后还是忍不住要回顾一下整个流程,有两方面的考虑:

  1. 对知识的一个总结
  2. 因为这是自己第一次写文章,也可以练习一下文笔和对Markdown的使用

搭建博客的初衷


  • 当然是为了装比(不不,作为一个程序员当然是为了慢慢树立属于自己的品牌)
  • 因为平常自己会看一些技术书籍,以前都是用纸质笔记本在写读书笔记和总结之类的,但是为了方便今后自己回顾和提倡绿色环保的理念还是选择了搭建一个博客

利用hexo搭建博客的步骤:


安装hexo

当然前提条件是你已经安装了node.js,安装node.js的同时会自带安装全球最大的包管理工具NPM,然后打开命令行工具依次 输入:

1
2
3
4
5
npm install hexo-cli -g //全局安装hexo
hexo init blog //在你自己想创建博客的目录下初始化博客项目
cd blog
npm install //安装依赖
hexo server //开启hexo服务器

执行完最后一条命令后你应该看到类似INFO Hexo is running at http://localhost:4000/. Press Ctrl+C to stop.的语句,那么访问http://localhost:4000/ 即可看到默认的landscape主题的网站

下载next主题并切换主题

下载就不多说,利用git直接克隆github上最新的next,具体可以参考next使用,然后在站点根目录,也即是blog目录下找到_config.yml 文件,在文件中找到 theme 关键字修改为如下所示:

1
theme: next

同样为了验证我们的主题切换是否成功,命令行工具输入:

1
hexo s

主题配置中踩过的坑

当然上一步我们已经成功的将我们的博客主题切换到了next,但肯定有很多骚年不满足于目前next的表现,于是就开始了next主题个性化和第三方功能的折腾当中,官网已经说的很详细,具体见next使用,下面就我自己踩过的几个坑做个特殊的说明:

多说user_id大坑

为你的博客添加多说评论很简单,只需要注册一个多说账号,然后在站点配置文件 _config.yml 中增加字段:

1
duoshuo_shortname: 你的多说域名中.duoshuo.com前面的字段

启用UA功能也很简单,只需要在next主题配置文件 _config.yml 中找到

1
2
3
4
5
duoshuo_info:
ua_enable: true
admin_enable: true
user_id: 0
admin_nickname: 博主

然后将ua_enable字段设置为true即可,但是这个admin_enable字段是干什么用的呢?这个字段是为了在评论区突出显示博主自己而需要配置的,当然为了彰显出主场的气势,我也准备将这个功能打开,于是我将admin_enable字段设置为了true,但是问题来了,官网上明显说的是当admin_enable设置为true是必须设置user_id和admin_nickname,admin_nickname字段好说,随便写个自己看着舒服的名字就可以了,可是这个user_id是什么鬼?于是我差点没将我的多说账号里面的每一个字段都当成user_id一遍又一遍的测试,最后还是无功而返,试着各种搜索也没有找到相关的解决方案。最后,在官网和主题配置文件里面找到了答案,如下:

1
2
3
4
5
6
7
8
# Make duoshuo show UA
# user_id must NOT be null when admin_enable is true!
# you can visit http://dev.duoshuo.com get duoshuo user id.
duoshuo_info:
ua_enable: true
admin_enable: true
user_id:
admin_nickname:

别人明明说了让你去http://dev.duoshuo.com 这个多说的开发者中心拿取user_id你却跑到http://antstrong.duoshuo.com 去闹了个天翻地覆,还有就是官网也明明给了你答案,如下图:
user_id说明
这时候真的是想说句日了狗了,同时也说明了自己不够细心,学东西太过于急切,也算是一个不大不小的教训吧,对了,最后贴一张最终的效果图吧:
效果图

打赏功能之坑

打赏功能不必多说,开始主要是不知道要怎么添加这个功能,后面发现我正在使用的next主题已经集成了此功能,只需要在主题配置文件中添加:

1
2
3
4
# 文章末尾显示打赏
reward_comment: 你的鼓励,我的动力!
wechatpay: 微信支付图片URL
alipay: 支付宝图片URL

总结


当然为了搭建这个博客,来来去去花了自己不少时间,因为自己也算一个小白,在很多方面都没有经验,所以只有靠着搜索引擎慢慢的收集资料,然后慢慢的消化慢慢的做出成果,最终,在踩了不少坑之后,这边笔记也相当于给自己的一个交代吧!哈哈,终于是完成了,当然完成也是一个开始,后面自己会尽力坚持在博客上多分享一些技术性的文章和自己的学习笔记,Live beautiful, come on!

antstrong's corner

Hello World

发表于 2016-12-05 | 分类于 折腾 | | 阅读次数

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

antstrong

antstrong

Live beautiful

5 日志
4 分类
8 标签
Github 掘金 Sina微博 知乎
© 2017 antstrong
由 Hexo 强力驱动
主题 - NexT.Mist