fetch

实现中的 fetch 是希望能比 XMLHttpRequest 更好地做网络请求。

1
2
3
4
5
6
7
8
9
10
fetch('/')
    .then(res => {
       if(res.ok) {
         return res.text();
       } else {
         throw new TypeError(res.statusText);
       }
    })
    .then(text => console.log(text.length))
    .catch(err => console.error(err.message));

注意点:

  1. fetch 仅在网络因素下 reject,业务的错误,如 502 或 404 等会 resolve,需要判断 response 是否 ok
  2. 默认不携带 cookie,需要明确指定
  3. 跨域时会受 CSP 控制影响,需要配置

Reference

JavaScript 中的零除

一直意味在 JavaScript 中也和别的语言一样会触发错误,所以一直依赖使用除法都先小心地做个判断。但偶然中却发现并不需要在做除法前判断,因为不会报错,只需要拿到结果后进行处理即可。

发现不会报错后,稍微去看了一下规定:

1
2
3
4
5
6
7
8
9
10
Infinity / Infinity = NaN
Infinity / 0 = Infinity
-Infinity / 0 = -Infinity
Infinity / nonZeroFinite = Infinity
-Infinity / nonZeroFinite = -Infinity
aPositive / Infinity = 0
aNegative / Infinity = -0
0 / 0 = NaN
aPositive / 0 = Infinity
aNegative / 0 - -Infinity

奇偶校验位

奇偶校验位是一种简单的错误检测码。

分为偶检验位和奇校验位两种。对于偶校验位来说,如果 01 序列中的 1 的个数是奇数,那么校验位是 1,使得添加校验位后的 1 的个数是偶数,否则校验位是 0;奇校验位刚好相反。

从定义来说,可以看到,奇偶校验仅能检测奇数个位数发生反转的错误,不能检测偶数个位发生反转的情况,也不能确定哪些位发生了反转,故不能纠错。
继续阅读“奇偶校验位”

Grunt files 扩展名注意点

假设 src 目录下有以下文件:

1
2
3
src/
├── a.js
└── c.test.js

然后使用以下 grunt 配置文件来把 src 里的 js 文件复制到 dest 目录,把扩展名改为 -min.js

1
2
3
4
5
6
7
8
9
10
11
12
grunt.initConfig({
  copy: {
    main: {
      expand: true,
      cwd: 'src/',
      src: '*.js',
      dest: 'dest/',
      filter: 'isFile',
      ext: '-min.js'
    }
  }
});

复制后的文件将是:

1
2
3
dest/
├── a-min.js
└── c-min.js

继续阅读“Grunt files 扩展名注意点”

Touch 事件备忘

过了一次文档,做个备忘。

Touch 接口

每一个单独的触摸点,不可变。

1
2
3
4
5
6
7
8
9
10
interface Touch {
    readonly attribute long        identifier;
    readonly attribute EventTarget target;
    readonly attribute long        screenX;
    readonly attribute long        screenY;
    readonly attribute long        clientX;
    readonly attribute long        clientY;
    readonly attribute long        pageX;
    readonly attribute long        pageY;
};

继续阅读“Touch 事件备忘”

postMessage

postMessage 被设计用来在窗口(window)间通信,特别地,用于跨域间的通信(可携带 cookie)。可支持在普通的页面、iframe / frame、用 open 打开的新窗口间使用。

使用的方法是:targetWindow.postMessage(message, targetOrigin),接收的事件是message

其中message不限定为字符串,targetOrigin是用来指定接收方的 Origin,不符合时浏览器禁掉该请求抛出异常,可以是 * ,但建议指定为具体的。

下面是一个单向通信的示例(A -> B)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// A domain
windowB.postMessage('just a message', 'http://bdomain');


// B domain
window.onmessage = function(e) {
    // for safety
    if (e.origin == 'http://bdomain') {
        // source origin
        alert(e.source);
        // message data
        alert(e.data);
    }
};

通过设置隐藏的跨域 iframe,然后通过该 iframe 可以实现跨域无刷新提交需求。

这里是一个 DEMO

References

  1. postMessage – MDN
  2. compability – Can I use

CORS

CORS(Cross-Origin Resource Sharing),这技术的提出主要是为了解决 Ajax 的跨域问题。如果是 GET 类型的跨域请求的话,还有 JSONP 这种简单的解决方法,但像 POST 这种就复杂了,所以提出了 CORS。

XDomainRequest

IE 在 IE8 时就开始提供了跨域方案 XDomainRequest ,有了 error、timeout、progress 等处理函数,可惜得是走得太前并且当初考虑 .net 系列多导致限制有些多。

比如,对于普通的 Ajax post 来说,一般会设置 Content-Type: application/x-www-form-urlencoded,但 XDomainRequest 不能设置 header,从而只能发送纯文本,这对于服务器端会带来些困扰。PHP 在这种情况下不会把提交的键值对放进 $_POST 变量中,而需要用 HTTP_RAW_POST_DATA 来获取再解析。

也没法发送 cookie 来做身份验证。

因为限制有些多,所以 ie10 后抛弃了 XDomainRequest 而采用 XMLHttpRequest Level 2 了。

下面是一个简单的例子
继续阅读“CORS”

语义化版本号

对于一个给定的版本号 MAJOR.MINOR.PATCH (主、次、补丁),其变化的规律是:

MAJOR version (主版本) 会在 API 发生不可向下兼容的改变时增大。
MINOR version (次版本) 会在有向下兼容的新功能加入时增大。
PATCH version (补丁版本) 会在bug以向下兼容的方式被修复时增大。

References

  1. [译]语义化版本管理
  2. Semantic Versioning 2.0.0