首页 > 技术文章 > 看源码积累知识点

JhoneLee 2018-10-23 17:04 原文

1. 如何判断Date对象是一个有效的Date对象

var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'

该问题来源于Stack Overflow,地址:

https://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript/12372720#12372720

其实只要简单的判断  date.getTime() === date.getTime()  就行,因为 NaN 不等于 NaN

 

2. 突破定时器的限制

  setTimeout 及 setInterval 里面针对第二个毫秒参数是有上限限制的,最大只能到2^31-1 毫秒,也就是24.8天,超过该数值造成溢出,函数会立即执行。所以在实际情况中出现需要长时间延时/重复,那么就需要引入 long-timeout

  https://www.npmjs.com/package/long-timeout

  而node-schedule 的定期执行正是基于此

那么long-timeout是怎么做的呢?

其实很简单,核心代码如下:

Timeout.prototype.start = function() {
  if (this.after <= TIMEOUT_MAX) {
    this.timeout = setTimeout(this.listener, this.after)
  } else {
    var self = this
    this.timeout = setTimeout(function() {
      self.after -= TIMEOUT_MAX
      self.start()
    }, TIMEOUT_MAX)
  }
  if (this.unreffed) {
    this.timeout.unref()
  }
}

超过了就递归调用就是

 

3. html 字符转义的科学写法

为了防止xss攻击,需要对字符中的 < >  " '  & 字符进行转义,有时候我们为了方便,用正则

a.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");

这种形式对字符串进行替换,这种写法对短字符串可能无所谓,但是如果是长字符串呢?还要正则全局匹配?

所以需要我们对字符串进行最少次数的操作进行字符替换

正好看了npm  escape-html 的源码,简言之就是通过match  /["'&<>]/  正则,得到匹配到的字符的类数组

然后forEach,替换拼接,效率得到了提升

 1 var matchHtmlRegExp = /["'&<>]/;
 2 function escapeHtml(string) {
 3   var str = '' + string;
 4   var match = matchHtmlRegExp.exec(str);
 5 
 6   if (!match) {
 7     return str;
 8   }
 9 
10   var escape;
11   var html = '';
12   var index = 0;
13   var lastIndex = 0;
14 
15   for (index = match.index; index < str.length; index++) {
16     switch (str.charCodeAt(index)) {
17       case 34: // "
18         escape = '&quot;';
19         break;
20       case 38: // &
21         escape = '&amp;';
22         break;
23       case 39: // '
24         escape = '&#39;';
25         break;
26       case 60: // <
27         escape = '&lt;';
28         break;
29       case 62: // >
30         escape = '&gt;';
31         break;
32       default:
33         continue;
34     }
35 
36     if (lastIndex !== index) {
37       html += str.substring(lastIndex, index);
38     }
39 
40     lastIndex = index + 1;
41     html += escape;
42   }
43 
44   return lastIndex !== index
45     ? html + str.substring(lastIndex, index)
46     : html;
47 }
View Code

 

4.在http协议上的安全设置

防止加载外域资源:主要利用Content-Security-Policy 报头设置  default-src 'self'  即仅加载本域的资源。

参考与 阮一峰老师的日志

http://www.ruanyifeng.com/blog/2016/09/csp.html

 

防止浏览器MIME嗅探:浏览器在未知文件类型或文件类型错误的情况下,会通过MIME嗅探进行猜测,自作主张的解析文件,把本不该是某种类型的文件瞎几把解析,导致受到攻击

就需要使用 X-Content-Type-Options   nosniff   禁止浏览器的二逼行为

 

5.webpack打包报以下错误(工程化向)

You may need an appropriate loader to handle this file type.
|       var AsyncHome = asyncComponent(appendAsyncReducer, epicSubject$, function () {
|         return process.env.SERVER ? require('./home')
>         : import(
|         /* webpackChunkName: "books" */
|         './home');
 @ ./server/ssr.js 15:0-34 167:25-34
 @ ./server/index.js

出错背景:

在一个webpack+react+jest+antd的项目中,搭建好的脚手架,无意中只更新了webpack,使webpack的版本从4.26 变为4.30,然后再运行项目,导致项目无法打包报出错误

出错原因:

因为webpack 需要依赖acorn-dynamic-import  和 acorn ,webpack更新后,webpack对acorn的依赖版本从5.7.4 变为6.1.1,而这种依赖来源于webpack自身的node_modules 中,而acorn-dynamic-import 同样依赖acorn,但是acorn-dynamic-import依赖的acorn在根node_modules中,导致出现如下依赖状况:

node_modules
  webpack
    node_modules
      acorn
  acorn
  acorn-dynamic-import

而根node_modules中的acorn版本依旧是5.7.4,导致webpack依赖的acorn-dynamic-import 包中使用的acorn版本和webpack本身使用的acorn版本不一致,导致打包失败,所以我们要做的就是重新更新所有的acorn包的版本并对包去重,执行以下两个命令

npm update acorn --depth 20   (更新acorn ,保险起见路径深度设为20)
npm dedupe  (包去重)

参考自:https://github.com/webpack/webpack/issues/8656 

 

 

如果执行完命令后报

TypeError: acorn.Parser.extend is not a function

at Object.<anonymous> (/Users/liyunjiao/mygithub/reactSPAScaffold/node_modules/webpack/lib/Parser.js:18:34)

    at Module._compile (internal/modules/cjs/loader.js:689:30)

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)

    at Module.load (internal/modules/cjs/loader.js:599:32)

    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)

    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

    at Module.require (internal/modules/cjs/loader.js:637:17)

    at require (internal/modules/cjs/helpers.js:22:18)

    at Object.<anonymous> (/Users/liyunjiao/mygithub/reactSPAScaffold/node_modules/webpack/lib/JavascriptModulesPlugin.js:7:16)

    at Module._compile (internal/modules/cjs/loader.js:689:30)

那么还是rm -rf  ./node_modules/*  指定webpack版本后重新npm install 吧

-------持续更新

 

推荐阅读