360前端星计划—JS/HTTP

559 阅读9分钟

JS

  • 三件套的各司其职
  • 结构,API,控制流分离设计UI组件
  • 插件和模板化,抽象组件模型(大坑)
  • 过程抽象优化局部API

各司其职

前端星学习第二天,从JS开始。前端三件套JS/HTML/CSS各司其职,最好不要相互干涉。如果要绑定一个事件操作DOM,最合适的方法是什么呢?

  • 方法一:直接操作DOM元素属性
  • 方法二:CSS通过class提前创建出变换的样式,然后操作classname或者id

第二个版本最大的好处是遵守了各司其职的原则,提高了代码的可维护性。

  • 方法三:纯CSS,创建并隐藏一个input checkbox组件,然后利用 选择器#id:checked + #DOMID进行样式的变更。还要配合label标签的for属性将checkbox与其他元素联动

第三版的缺点是兄弟选择器在较低版本的浏览器上可能不兼容,移动端不用考虑这个。

如何设计复杂的UI组件

以轮播图为例,特征是无操作时图片定时更换,鼠标聚焦或者点击图片不轮换。

结构分析&设计

图片结构

首先数张图片重叠在一起,我们可以使用列表+绝对定位的方式进行排列。 HTML结构大概是:

<div>
    <ul>
    <li><img></li>
    <li><img></li>
    <li><img></li>
    </ul>
</div>

选择图片使用classname来进行筛选,比如分成两组img_itemandimg_item_selected。 图片之间的切换和动画效果可以使用transition实现。

控制结构(小圆点)

用a标签实现next和previous的标志,用div+span实现小圆点。

API设计&实现

  • class Slider this.container this.items
  • getSelectedItem() 获得选中的元素(DOM) 直接使用querySelector就可以选出当前图片的列表DOM
  • getSelectedItemIndex() 获得选中的元素是列表的第几个元素,在this.items里面查询返回的DOM的index
  • slideTo(idx) 鼠标移动到小圆点 图片直接展示。主要是进行两个操作,当前图片的去选中和新图片的选中。
  • slideNext() 这两个就是点击左右移动标签发生的事件。
  • slidePrevious() 获取当前图片的index然后加减1,调用slideTo(idx)实现功能

最后可以使用setInterval调用slideNext()来进行常规的轮换

自定义事件

const detail = {index:idx}
const event = new CustomEvent('slide',{bubbles:true,detail})
this.container.dispatchEvent(event);

mouseover & mouseout

小圆点控制器组要监听这两个事件,前者切换小圆点和图片并停止定时器,后者开始定时器 使用clearIntervalsetInterval来进行操作

局部细节控制

用户操作无法控制

如果一个click操作是渐进式地移除一个元素块,或者说有延迟。那么用户可能会多次点击从而在后续操作的时候不存在要移除的方块从而发生错误。

  • 方案1:手动实现节流/防抖函数,这个场景节流函数更有效
  • 方案2:addEventListener('',callback,{once:true}) 但是兼容性可能不好
  • 方案3:在函数内部将指向函数的指针设为null,这样就再也不能调用了

过程抽象

高阶函数:自身输入函数或者返回函数。

once function

这个函数传入一个callback,返回一个函数,返回函数中包含传入的callback,执行一次之后就置null。

function once(fn){
    return function(...args){
        if(fn){
            let ret = fn.apply(this,args);
            fn = null;
            return ret;
        }
    }
}

throttle

const throttle = function (fn, delay=1000,atleast=500) {
    let timer, prevtime;
    return function(...args){
        var now = Date.now();

        if(!prevtime) previous = now;
        
        if((now - prevtime) > atleast){
            fn(...args);
        }else{
            clearTimeout(timer);
            timer = setTimeout(()=>{
                fn()
            },delay);
        }
    }
}

debounce

function debounce(fn,dur){
    dur = dur || 100;
    var timer;
    return function(){
        clearTimeout(timer);
        timer = setTimeout(()=>{
            fn.apply(this,arguments);
        },dur)
    }
}

消费者

function consumer(fn,time){
    let tasks = [],timer;
    
    return function(...args){
        tasks. push(fn.bind(this,...args));
        if(timer == null){
            timer = setInterval(()=>{
                tasks.shift().call(this)
                if(tasks.length <= 0){
                    clearInterval(timer);
                    timer = null;
                }
            },time)
        }
    }
}

toggle(declarative)

function toggle(...actions){
    return function(...args){
        let action = actions.shift();
        actions.push(action);
        return action.apply(this,args);
    }
}

使用声明式编程最大的好处就是容易扩展,不用修改繁琐的if..else。

loop进行抽象->生成器

function * loop(list, max=Infinity){
    let i = 0;
    while(i < max){
        yield list[i++ % list.length;]
    }
}

function toggle(...actions){
    let action = loop(actions);
    return function(...args){
        return action.next().value.apply(this,...args);
    }
}

web标准

概述

  • WEB = World Wide Web
  • WEB标准其实是构成WEB基础,运行和发展的一系列标准的总称,并不是由一家标准不组织制定的

HTTP

HTTP一系列的协议是由IETF(互联网工程任务组)标准组织制定的,TCP也是。

  • HTTP/0.9 定义了最简单的通信协议,只有GET方法
  • HTTP/1.0 是0.9版本的扩展,增加了HEAD,POST方法;版本号可选;响应码
  • HTTP/1.1 keep-alive;更好的缓存;明文发送
  • TLS1.3 加密,更好的安全性
  • HTTP/2.0 多路复用/header压缩/二进制传输/server push
  • HTTP3 基于QUIC协议(UDP)

ECMA

ECMA-262 也就是 ECMA Script标准。

W3C

制定了HTML,CSS和DOM的相关部分标准

  • BOM(Browser Object Model) 涉及window,location,navigator,screen and history对象
  • DOM(Document Object Model) level1主要是HTML/XML的底层结构,level2/3在此基础上加入了更多交互能力。比如 DOM Core,DOM View,DOM Event,DOM Style

whatwg

由浏览器开发商组成的一个组织。一些浏览器API的标准。

HTTP

HTTP2.0以下是基于TCP协议的,但是HTTP3.0变成了基于UDP,加快了连接速度。

结构

<method><request-URL><version>
<headers>

<entity-body>

<version><status><respon-phrase>
<headers>

<entity-body>

请求/响应报文基本上是由首行表示类型,协议版本和方法,然后是headers+空行。最后是数据实体

请求类型

  • GET
  • POST
  • PUT
  • DELETE
  • OPTIONS
  • HEAD
  • PATCH

状态码

  • 1XX: Informational 接受的请求正在处理
  • 2XX: Success 请求正常处理完毕
  • 3XX Direction 需要进行附加操作以完成请求
  • 4XX:Client Error 服务器无法处理
  • 5XX:Server Error 服务器请求出错

1xx

  • 101 切换协议,比如升级到websocket

2XX

  • 200 OK
  • 204 No Content 成功处理但是返回不含body,客户端发信息但是不返回新信息
  • 206 Parital Content 客户端进行了范围请求(大文件下载)

3XX

请求成功但是需要额外的一些操作以返回结果

  • 301 Moved Permanently 改资源已经被分配了新的URI,永久重定向,会使用缓存
  • 302 Found 临时重定向,将来可能还发生变化
  • 303 See Other 表示应该使用GET method。 可能发生在使用post 访问了一个程序
  • 304 Not Modified 请求报文中有额外条件,但是未满足。或者是在分级缓存机制中

4XX

  • 400 Bad Request 请求报文有语法错误
  • 401 Unauthorized 需要认值,会弹出窗口
  • 403 Forbidden 请求报文被服务端拒绝,可能不会给出原因
  • 404 Not Found 服务器没有找到请求的资源,或者请求被拒绝
  • 413 Payload Too Large 请求实体过大 服务器限制上传大小

5XX

  • 500 Internal Server Error 服务器端在处理请求时发生了错误
  • 502 Bad Gateway 作为网关或者代理服务器时,上游服务器异常
  • 503 Service Unavailable 服务器不可用
  • 504 Gateway Timeout 作为网关或者代理服务器时,上游服务器处理超时

URL

URI : Uniform Resource Identifier 。为了定位某个资源,用来唯一标识互联网上的信息资源,包括URL URN email地址也是URI,但是不是location

URL: uniform resource locator 统一资源定位器 协议://(user@) hostname.com: port 默认80 一般不带/path? 这是路由 schema://(user:pass@)hostname

  • fpt http https
  • user 很少用 不安全
  • hostname 直接是IP地址或者是domain domain需要DNS解析
  • port 默认80 公开的资源一般不带,难以记忆
  • /path router路由,
  • 搜索参数,
  • hash 代表返回的文件的某一个片段,使用hash作为锚点 anchor

URN: 永久统一资源定位符 很少用

Header分类

通用

  • Date
  • Connection

请求

  • User-Agent
  • Accept

响应

  • Server
  • Last-Modified

实体

  • Content-Type
  • COntent-Length

扩展/自定义

  • X-Cache
  • X-Name 一般以X为开头

Cookie

Cookie是服务端设置的,在响应中是Set-Cookie,请求中是Cookie。响应头中可以有多个Set-Cookie。

  • path
  • domain:如果请求地址同站但是url没有匹配 则不会携带cookie
  • samesite: 同站是否发送cookie,默认值已从None变为Lax
  • expires
  • max-age 这两个都是设置过期时间
  • httponly: 用户不能操作
  • secure: 加密 https

安全策略

  • XSS盗取Cookies,设置httponly可以防止用户直接获取Cookies
  • CSRF漏洞,设置token/samesite

Context-type

  • 在respones里面设置主要是返回的数据格式
  • 在request里面设置是提交的数据格式,一般是POST,PUT,运行以下几种格式
    • application/x-www-form-urlencoded 主要是数据通过keyvalue格式放在url
    • multipart/form-data 文件上传
    • application/json 上传JSON格式数据
    • text/xml xml的数据格式,已经少见

性能优化

主要已经总结在我另一篇blog里 juejin.cn/post/684490…

内容压缩(补充)

主要是针对大容量文本进行压缩,手动调用压缩算法然后在request header里面使用content-encoding标注可接受的压缩格式。后端response的时候给出自己使用的压缩算法通知浏览器解压缩。 图片和视频,浏览器有自己的压缩方式。

缓存

  • 强缓存
  • 协商缓存
  • 缓存位置
  • 其他设置

强缓存

  • no-cache 缓存但是要发送request验证
  • no-store 不缓存
  • max-age/expires 设置过期时间,推荐max-age,expire有本地时间修改的问题

协商缓存

协商缓存在强缓存失效/没命中的情况下使用,协商缓存命中返回304

  • Last-Modified---If-Modified-Since 有文件没变但是时间戳改变的问题
  • Etag---If-None-Match 更准确

其他设置

  • max-stale 缓存可以提供过期文件或者强制一段时间不过期
  • min-fresh 在未来s秒内文档保持有效
  • only-if-cached 当缓存有副本,客户端才获取副本

缓存位置

  • Service Worker 可以控制缓存
  • Memory Cache
  • Disk Cache (较大文件优先DISK)
  • Push Cache(HTPP2)

抓包工具

  • Wireshark
  • Fiddler
  • 开发者工具

发包工具

  • telnet/curl
  • Fiddler
  • Tamper for Firefox
  • Postman
  • Paw for OSX