zf-6-koa的使用和源码 (12天)

1.Promise中await的问题

function fn(){
    return new Promise((resolve,reject)=>{
        resolve([1,2,3]);
    })
}
async function getData(){
    await fn(); 
    console.log(1);
}
getData();
Promise.resolve().then(data=>{
    console.log(2);
});

2.编码问题

  • ASCII -> ANSI(GB2312) -> GBK -> GB18030 -> Unicode -> UTF-8
  • base64编码 缺点比以前大
  • 编码问题
var iconv = require('iconv-lite'); // node中的编码转化
function readGBKText(pathname) {
    var bin = fs.readFileSync(pathname);
    return iconv.decode(bin, 'gbk');
}

3.Buffer方法

  • 分配方法 alloc 、from
  • slice toString concat isBuffer length(split)

4.核心模块 fs 、event、 path、stream

fs:

  • readFile writeFile
  • (open read write)
  • mkdir access stat unlink
  • createReadStream createWriteStream (pipe用法)

event:

  • on emit off once (newListener)

path:

  • join resolve extname dirname __dirname __filename

    流的类型:

  • 1)可读(on(‘data’),on(‘end’)) req

  • 2)可写 write.end res

  • 3)双工

  • 4)转化流 lib createGzip

5.HTTP (tcp用法)

1).一个页面从输入url到页面加载完成显示,这个过程做了什么?

  • 1). 浏览器通过DNS将url地址解析为ip (如果有缓存直接返回缓存,否则递归解析)
  • 2). 通过DNS解析得到了目标服务器的IP地址后,与服务器建立TCP连接。
    • ip协议: 选择传输路线,负责找到
    • tcp协议: 三次握手,分片,可靠传输,重新发送的机制 (tcp)
  • 3).浏览器通过http协议发送请求 (增加http的报文信息)
  • 4).服务器接受请求后,查库,读文件,拼接好返回的http响应
  • 5).浏览器收到html,开始渲染 (浏览器的渲染原理)
  • 6).解析html为dom,解析css为css-tree,最终生成render-tree 阻塞渲染
  • 7).遍历渲染树开始布局,计算每个节点的位置大小信息
  • 8).将渲染树每个节点绘制到屏幕
  • 9).加载js文件,运行js脚本
  • 10).reflow (样式)与repaint(位置)

OSI协议分层:

  • 应用层 HTTP,FTP,DNS (与其他计算机进行通讯的一个应用服务,向用户提供应用服务时的通信活动)
  • 传输层 TCP(可靠) UDP 数据传输 (HTTP -> TCP DNS->UDP)
    • 网络层 IP 选择传输路线 (通过ip地址和mac地址)(使用ARP协议凭借mac地址进行通信)
    • 链路层 网络连接的硬件部分

2).Http与Https的区别:

缺陷:
- 1).Http本身不具备加密的功能,HTTP 报文使用明文方式发送
- 2).无法确认你发送到的服务器就是真正的目标服务器
- 3).无法阻止海量请求下的 DoS 攻击
- 4).内容被篡改

  • HTTPS 是 HTTP 建立在 SSL/TLS 安全协议上的。 (信息加密,完整校验,身份验证)

3).URI和URL的区别

  • URI(Uniform Resource Identifier)是统一资源标识符,在某个规则下能把这个资源独一无二标示出来
  • URL(Uniform Resource Locator) 统一资源定位符,表示资源的地点

4).HTTP1.1版本特性

  • 长链接:建立链接后可以发送多次请求
  • 管线化:不用等待可以直接发送下一个请求
  • 断点续传:206 bytes

5).常见的http状态码

  • 200、204、206、301、302、304、400、401、403、404、500、503

6).常用的http方法有哪些

  • GET 获取资源
  • POST 向服务器端发送数据,传输实体主体
  • PUT 传输文件
  • HEAD 获取报文首部
  • DELETE 删除文件
  • OPTIONS 询问支持的方法

7).Jsonp的原理 (不符合规范的)

8).页面的性能优化

img

  • 缓存
    强制缓存 & 对比缓存

    from memory cache 和 from disk cache
    查找优先级:

    • Service Worker (PWA) cacheApi 离线缓存
    • Memory Cache 网页关闭则失效 (几乎所有的请求资源)
    • DiskCache
    • 网络请求
      对于大文件来说,大概率是不存储在内存中的,当前系统内存使用率高的话,文件优先存储进硬盘
  • gzip压缩 重复率越高 压缩越高

  • 本地存储:localStorage,sessionStorage,session,cookie,indexDB,cacheApi

  • CDN: 内容分发网络,实现负载均衡,并且就近返回内容

  • defer & async / preload & prefetch

    • defer 和 async 在网络读取的过程中都是异步解析
    • defer是有顺序依赖的,async只要脚本加载完后就会执行
    • preload 可以对当前页面所需的脚本、样式等资源进行预加载 vue 路由懒加载
    • prefetch 加载的资源一般不是用于当前页面的,是未来很可能用到的这样一些资源

HTTP相关Header内容

  • 缓存Header
    • 强:Cache-Control && Expires
      • private 客户端可以缓存
      • public 客户端和代理服务器都可以缓存
      • max-age=60 缓存内容将在60秒后失效
      • no-cache 需要使用对比缓存验证数据,强制向源服务器再次验证 (没有强制缓存)
      • no-store 所有内容都不会缓存,强制缓存和对比缓存都不会触发 (不缓存)
    • 对比:Last-Modified & If-Modified-Since / ETag & If-None-Match
  • 跨域:Access-Control
  • 压缩:Content-Encoding : gzip
  • 范围请求:range
  • 防盗链:referer (防止盗用链接)
  • 用户内核:user-agent
  • 单主机多域名:host
  • 多语言:accept-language
  • 文件上传:Content-Type:multipart/form-data
  • 文件下载:Content-Description

6.KOA

  • compose应用
let fn = this.arr.reduce((a, b, index) => (...args) =>
    Promise.resolve(a(() => b(...args)))
)(() => {}).then(()=>{
    console.log('ok')
})
  • async + await
 const dispatch = async (index) => {
    if(index === this.arr.length) return;
    return this.arr[index](()=>dispatch(index+1));
};
return dispatch(0);

下周 1-4 webpack训练营 周六flutter 两个周六

node进程

HTTP无状态的

不知道每次谁来了

  • cookie 是存放到 浏览器上的 ,服务器可以设置,每此请求时会带上cookie

  • cookie 不安全 不能存放敏感信息

  • session 服务端(基于cookie) 服务器的内存中,-》 redis 数据库 (get set)

compose.js
// 反柯里化 让某个函数 跨到应用的范围
Object.prototype.toString.call();
// grunt r.js gulp fis3 webpack rollup parcel 0配置
Function.prototype.uncurrying = function(){ // 
    return (str)=>{
        return this.call(str);
    }
}   
let toString = Object.prototype.toString.uncurrying();
console.log(toString('hello'));
// reduce 实现组合
let app = {
    arr:[],
    use(fn){
        this.arr.push(fn);
    },
    compose(){
        // reduce 那一节  redux的源码
        return this.arr.reduce((a,b)=>(...args)=> Promise.resolve(a(()=>b(...args))))(()=>{})
        // const dispatch = async (index)=>{
        //     if(index === this.arr.length) return;
        //    let middle =  this.arr[index];
        //    return middle(()=>dispatch(index+1));
        // }
        // return dispatch(0);
    },
    run(){
        this.compose().then(()=>{
            console.log('ok');
        })
    }
}
//add  len   sum
app.use((next)=>{
    console.log(1);
    next();
})
app.use((next)=>{
    console.log(2);
    // next();
})
app.use((next)=>{
    console.log(3);
    next();
})

app.run();
cookie.js
// 基本的设置cookie和获取cookie

const http = require('http');
const querystring = require('querystring');
const sign = (value)=>{
    // + / = 浏览器不支持
    return require('crypto').createHmac('sha256','zf').update(value).digest('base64').replace(/\/|\+|\=/g,'');
}
http.createServer((req,res)=>{
    let arr = [];
    res.setCookie = function(key,value,options={}){
        let opts = [];
        if(options.domain){
            opts.push(`domain=${options.domain}`)
        }
        if(options.maxAge){
            opts.push(`max-age=${options.maxAge}`)
        }
        if(options.httpOnly){
            opts.push(`httpOnly=${options.httpOnly}`)
        }
        if(options.signed){ // 加盐算法 
            value =  value + '.' + sign(value)
        }
        arr.push(`${key}=${value}; ${opts.join('; ')}`);
        res.setHeader('Set-Cookie',arr);
    }
    req.getCookie = function(key,options = {}){
        let obj = querystring.parse(req.headers.cookie,'; '); // a=b; c=d; www=xxx  a=b&c=d
        if(options.signed){
            let [value,s] = obj[key].split('.');
            let newSign = sign(value);
            if(s === newSign){
                return value;
            }else{
                return undefined;
            }
        }
        
        return obj[key];
    }
    if(req.url === '/write'){
        // 服务端 不能跨域设置cookie 可以给子域设置
        // www.baidu.com  
        // music.baidu.com
        // domain 限制某个域可以访问
        // path在哪个路径下可以访问cookie 以path开头的都能访问到 一般不设置 
        // expires、max-age 过期时间 缓存 如果做一些电商网站 (续命)
        // httpOnly 只能服务器操作

        // 客户端能村改cookie 仿造请求
        // res.setHeader('Set-Cookie',['name=zf; domain=.zhufeng.cn; max-age=10; httpOnly=true',`age=10`]);
        res.setCookie('name','zf',{domain:'.zhufeng.cn'});
        res.setCookie('age','10',{httpOnly:true});
        res.end('write ok');
        return 
    }
    if(req.url == '/visit'){
        // signed:true 表示 签名  不被用户所篡改
        let visit = req.getCookie('visit',{signed:true});
        if(visit){
            visit = visit-0+1;
            res.setCookie('visit',visit+'',{httpOnly:false,signed:true});
        }else{
            visit = 1
            res.setCookie('visit','1',{httpOnly:true,signed:true});
        }
        res.end(`当前第${visit}次访问`)
    }
    if(req.url === '/read'){
        res.end(req.getCookie('name') || '空');
    }
    
}).listen(3000);
server.js
const http = require('http');

http.createServer((req,res)=>{
    // script标签是支持跨域
    if(req.url === '/jsonp'){
        res.end(`fn({name:'zf'})`);
    }
}).listen(3000);
session
let http = require('http');
let uuid = require('uuid');
let querystring = require('querystring')
let cardName = 'tian';
let session = {}; // 存到内存中 数据库,数据挂了 问题就是持久化丢了 
let server = http.createServer((req,res)=>{
    let arr = [];
    res.setCookie = function(key,value,options={}){
        let opts = [];
        if(options.domain){
            opts.push(`domain=${options.domain}`)
        }
        if(options.maxAge){
            opts.push(`max-age=${options.maxAge}`)
        }
        if(options.httpOnly){
            opts.push(`httpOnly=${options.httpOnly}`)
        }
        if(options.signed){ // 加盐算法 
            value =  value + '.' + sign(value)
        }
        arr.push(`${key}=${value}; ${opts.join('; ')}`);
        res.setHeader('Set-Cookie',arr);
    }
    req.getCookie = function(key,options = {}){
        let obj = querystring.parse(req.headers.cookie,'; '); // a=b; c=d; www=xxx  a=b&c=d
        if(options.signed){
            let [value,s] = obj[key].split('.');
            let newSign = sign(value);
            if(s === newSign){
                return value;
            }else{
                return undefined;
            }
        }
        
        return obj[key];
    }
    if(req.url === '/wash'){
        let id = req.getCookie(cardName)
        if(id && session[id]){ // 有卡
            session[id].mny -=100;
            res.end('current money is # '+session[id].mny)
        }else{
            let cardId = uuid.v4();
            session[cardId] = {mny:500};
            res.setCookie(cardName,cardId);
            res.end('current money is # 500 ')
        }
    }
    res.end('Not Found')
}).listen(3000);

// jwt json web token (基于cookie原理)


// localStroage sessionStorage cookie session 区别
// localStroage 不能跨域 最多能存 5m 超过丢失 发请求的时候不会自动带上
// indexDB
// sessionStorage 浏览器关闭丢失
// cookie 在header上 每次请求自动带上 解决无状态的问题 最多4k 浪费流量
// session 基于cookie 存到服务器上

// 前后端分离 cookie 不支持
// ssr
// jwt express + cookie + session express 中间件 周六

// mongoose 2小时就能搞定 增删改查
test.js
function fn(){
    return new Promise((resolve,reject)=>{
        resolve([1,2,3]);
    })
}
async function getData(){
    // await fn();  
    // Promise.resolve(fn()).then(()=>{
    //     console.log(1)
    // })
    // resolve中如果放了一个promise 会等待这个promise 成功后在继续执行
    new Promise((resolve,reject)=>resolve(fn())).then(()=>{
        console.log(1);
    })
}
getData();
Promise.resolve().then(data=>{
    console.log(2);
});

// 2 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值