从vue源码角度分析v-text和{{}}插值的区别

问题描述:

在做生成表格的需求时,遇到需要手动在单元格输入文字,并生成表头:即实现可编辑效果的功能。发现可以通过设置标签的contenteditable属性来实现任意html元素可编辑,并且把用户输入赋值给变量。这时,在vue框架下,就想到了双向数据绑定绑定输入值。但因为这不是input表单标签,无法直接使用v-model指令,一般是使用创建组件的方式实现双向数据绑定。但我当时第一直觉想到的是双花括号方式绑定。并遇到了一个坑,在此记录下来。

Read More

inline-block元素的诡异样式问题

记录一次inline-block引起的诡异样式错位


想在colorPicker后面加一个icon,点击增加就可以继续增加colorPicker,
用了一个div套i标签,然后设置div为inline-block,但是发现这个div和前面的colorPicker的div怎么都不在一条水平线上。特别尴尬。
同样都是inline-block布局,到底哪里出了问题。

Read More

4xx

这是我阅读http协议4xx状态码的笔记

4xx开头的表示这是客户端出现了错误。

除非请求是head方法,否则服务端都应该在请求体中描述出错的情况,永久错误还是临时性错误。

400 Bad Request

表示请求语法错误,而且这个请求也不应该被重复提交。

401

401 vs 403

401 和 403的区别是,401可能是你认证不通过,也有可能是你压根没有认证那个header,所以你可以修改一下认证重新提交相同的请求,403则不管你有没有认证,即便是认证通过了,但你依然没有权限访问这个uri.

403 Forbidden vs 401 Unauthorized HTTP responses

用nodejs的http模块和fs模块。搭建一个简单的服务器。路由规则用正则。

创建一个服务端

node可以发送请求,也可以监听某个端口,响应http请求。

创建服务端,并监听2016端口。

处理get请求:get.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
// 引用http模块
var http = require("http");

// 引用url模块
var url = require("url");

// 引用querystring模块
var querystring = require("querystring");

http.createServer(function (request, response) {
var objectUrl = url.parse(request.url);

var objectQuery = querystring.parse(objectUrl.query);

response.writeHead(200, {
"content-type": "text/html"
});

// 输出url的各项参数
response.write("<h1>objectUrl</h1>");
for (var i in objectUrl) {
if (typeof (objectUrl[i]) != "function")
response.write(i + "=>" + objectUrl[i] + "<br>");
}

// 输出url中的query的各项参数
response.write("<h1>objectQuery</h1>");
for (var i in objectQuery) {
response.write(i + "=>" + objectQuery[i] + "<br>");
}

response.end();
}).listen(2016);

在本文件的目录下,运行node get.js

然后浏览器输入localhost:2016回车。

request.url表示请求的url。如:”/“,如果你输入form。则会返回”/form”。

比如你输了这样一串url:

1
http://localhost:2014/form?name=kenzi&age=20&sex=female

url.parse这个模块会对url进行解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=kenzi&age=20&sex=female',
query: 'name=kenzi&age=20&sex=female',
pathname: '/form',
path: '/form?name=kenzi&age=20&sex=female',
href: '/form?name=kenzi&age=20&sex=female'
}

url模块的使用方法

参考

Accessing the HTTP message body (e.g. POST data) in node.js

http://www.dotnetcurry.com/nodejs/1144/nodejs-html-static-pages-website

https://github.com/dotnetcurry/node.js-html-static-content/blob/master/server.js

https://cnodejs.org/topic/51738afd6d38277306ef98ad

mongoose quik start

题外话

因为刚学http协议,很想自己搭建一个服务器实践一下。比如实现一个简单的点赞功能,登录功能等。而且一直想学习node所以选了node作为后端语言。如果以后有机会,也许会用其他语言试一试。网上搜索的很多例子都是nodejs+express框架。使用express框架可能会方便很多。不过我认为还是应该从基层写起,这样才会知道为啥要使用某个框架,框架帮你处理了什么。

字符串编码

之前对url进行编码的时候遇到过encodeURI和encodeURIComponent,如今要设置cookie的value又遇到了escape(),并且提示说,尽量不用这个方法。

那么这些方法有什么区别呢?

escape

首先这个方法被不推荐使用。如上图所示。

它不会对ASCII字母 数字 * @ - _ + . /这些符号进行转义。

下面这张table表示了escape方法对哪些字符进行编码:

下面这张table表示了escape方法对哪些字符不进行编码:

encodeURI

下面内容部分来自于知乎答案:黄家兴的回答

他用来对完整的url编码。它不会对:ASCII字母 数字 ~ ! @ # $ & * ( ) = : / , ; ? + ‘ 这些符号进行转义。

1
2
3
4
encodeURI("http://www.cnblogs.com/season-huang/some other thing");

//result
"http://www.cnblogs.com/season-huang/some%20other%20thing";

其中,空格被编码成了%20。但是如果你用了encodeURIComponent,那么结果变为

1
"http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2Fsome%20other%20thing"

看到了区别吗,连 “/“ 都被编码了,整个URL已经没法用了。

下面这张table表示了encodeURI方法对哪些字符进行编码:

下面这张table表示了encodeURI方法对哪些字符不进行编码:

encodeURIComponent

他用来对url的部分query参数进行编码。它不会对ASCII字母 数字 ~ ! * ( ) ‘这些符号进行转义。

1
2
3
4
var param = "http://www.cnblogs.com/season-huang/"; //param为参数
param = encodeURIComponent(param);
var url = "http://www.cnblogs.com?next=" + param;
console.log(url) //"http://www.cnblogs.com?next=http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2F"

下面这张table表示了encodeURIComponent方法对哪些字符进行编码:

下面这张table表示了encodeURIComponent方法对哪些字符不进行编码:

总结

escape不推荐使用

encodeURIComponent会毁掉整个url,他只适用于当一个url是另一个url的参数时,对其进行编码

encodeURI可以对完整的url进行编码。

题外话

这些数据是我用一下代码生成的:

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
var arr1 = [];
var arr2 = [];
var arr3 = [];
var arr4 = [];
var arr5 = [];
var arr6 = [];
for (var i = 0; i < 127; i++) {
var char = String.fromCharCode(i);
if (encodeURI(char) == char) {
arr1.push({
charcode: i,
character: char,
encodeURI: encodeURI(char),
});
}
if (encodeURI(char) !== char) {
arr2.push({
charcode: i,
character: char,
encodeURI: encodeURI(char),
});
}
if (escape(char) == char) {
arr3.push({
charcode: i,
character: char,
escape: escape(char),
});
}
if (escape(char) !== char) {
arr4.push({
charcode: i,
character: char,
escape: escape(char),
});
}
if (encodeURIComponent(char) == char) {
arr5.push({
charcode: i,
character: char,
encodeURIComponent: encodeURIComponent(char),
});
}
if (encodeURIComponent(char) !== char) {
arr6.push({
charcode: i,
character: char,
encodeURIComponent: encodeURIComponent(char),
});
}
}

然后用console.table(arr1)就可以在控制台打印了。

然而console.table这么方便有木有可以直接把array转成table的api,直接显示在网页上?上网找了一下貌似不太可心。而且这么基础的程序我希望能用原生js实现。so,做了个轮子,把array转成table。基本实现了console.table的用法。传送门

http协议学习笔记

有部分内容来自Unacceptable Browser HTTP Accept Headers (Yes, You Safari and Internet Explorer)

报头详解

Accept 深入理解

属于请求头。客户端对服务端的协商。

表示接受的 MIME type.

MIME(Multipurpose Internet Mail Extensions) 表示多功能 Internet 邮件扩充服务。本来是用来定义邮件接受的媒体类型。后来被应用到http协议上后,内容就变得多种多样了。一共有七种
text,img,video,audio,multipart,application,
其中他们还有子类。比如text/html,text/plain,img/jpeg,img/gif等。

格式为:*/*;q=float 用分号分隔; 默认情况为q=1。q表示用户对某种类型的接受程度。

比如:chrome 浏览器下:

1
2
3
GET /Protocols/rfc2616/rfc2616-sec7.html HTTP/1.1
Host: www.w3.org
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

表示:

如果有text/html image/webp application/xhtml+xml这些格式最好。100%

如果上面的都没有,给我xml格式。90%

如果还是没有就给我啥都行。80%

再比如:

1
Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,text/html;level=2;q=0.4, */*;q=0.5

text/html;level=1 = 1

text/html = 0.7

text/plain = 0.3

image/jpeg = 0.5

text/html;level=2 = 0.4

text/html;level=3 = 0.7

我在想,请求行里的url的扩展里已经包括了资源的类型:.html,.jpeg等,为什么还要通过accept告诉服务器自己接受什么类型的文件呢?猜想直接指明类型会更快的响应请求。省的解析url里的类型。也有的不一定就能返回特定的指定类型,如果没有,也可以用其他类型代替。有一定的容错性。而且不一定url的请求就是一个指定的文件,可能只是某个文件夹。

不过听说,这些服务商都不用accept:

As stated, Twitter’s REST API doesn’t use the Accept header for content-negotiation, they use extensions on the URL ‘.json’ and ‘.xml’.

Rails disables the Accept header by default.

Frameworks can enhance performance by ignoring the Accept header and relying on ‘.xml’-like extensions.

As such the next release of the Recess Framework, too, will disable Accept header based content-negotiation by default.

这里的twitter就是直接通过解析扩展来确定类型的。

因为不同的浏览器对于某种类型的文件都有自己特定的accept定义,告诉服务器自己接受什么类型的文件。
如:firefox浏览器对于html文件的accept是:

text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

表示

Dear host,
I want the resource in an HTML or XHTML format. If you cannot serve me this way, I’ll take it in an XML instead. If you can’t even give it to me in XML, well, I’ll take anything you’ve got!
Love,
Firefox

ie 呢,就发一大堆:

image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, /

具体不同浏览器的文件类型对应的accept形式

content-type

content-type不管是请求还是响应都应该有。

响应中的content-type很好理解。通过请求中的accept来告知响应内容的类型。

那么请求中的content-type又是什么意思呢?

如果是post方法,那么空格后的那个message-body 里的格式就可以由content-type来传达。比如form。application/x-www-form-urlencoded or multipart/form-data

但如果是get方法呢?为什么需要这个东西?

我发现如果把响应中的content-type写成text/html 刷新时浏览器会渲染html页面。而如果把content-type写成img/jpeg,刷新chrome浏览器的时候会直接下载文件。可能这就是chrome浏览器针对http协议的一些设置。看来了解http协议这种约定俗称的规范,可以让浏览器帮助完成一些事情。

区别

content-type和accept有啥区别呢?虽然都规定了mime的类型,
缓存机制:

HTTP定义了3种缓存机制:
l Freshness allows a response to be used without re-checking it on the origin server, and can be controlled by both the server and the client. For example, the Expires response header gives a date when the document becomes stale, and the Cache-Control: max-age directive tells the cache how many seconds the response is fresh for.
l Validation can be used to check whether a cached response is still good after it becomes stale. For example, if the response has a Last-Modified header, a cache can make a conditional request using the If-Modified-Since header to see if it has changed.
l Invalidation is usually a side effect of another request that passes through the cache. For example, if URL associated with a cached response subsequently gets a POST, PUT or DELETE request, the cached response will be invalidated.

也就是说post发送的东西都不会被缓存,get方法发送的会被缓存哦。

参考

面向站长和网站管理员的Web缓存加速指南
Hypertext Transfer Protocol — HTTP/1.1
HTTP协议详解
输入网址之后发生了什么

初探promise

插件

今天实现了一个插件的动画,就是纸从折叠到展开的效果。主要用css3的tansition实现。js监听第一个列表rotate结束(监听transitionend事件),然后开始第二个rotate开始,transition结束后,再开始第三个的展开。回调地狱有木有。于是学了一下promise规范。发现es6已经有了原生的方法。就没有用库。看了回调地狱的官网(居然有官网),感觉概念清晰了很多。按照里面的方法重构了代码。看起来清晰多了。

Read More