介绍一下HTTP的发展史
- HTTP/0.9 – 单行协议 ,只有
GET - HTTP/1.0 – 构建可扩展性,协议版本信息、状态码、http头部信息
- HTTP/1.1 – 标准化的协议,连接可以复用,缓存控制机制,内容协商机制,Host头(能够使不同域名配置在同一个IP地址的服务器上)
http
超文本传输协议,是以无状态的请求应答方式运行的协议,明文传输
无状态是因为它本身不存储任何信息
https
加密的http,由于http天生明文的特点,整个传输过程完全透明数据,所以产生了https。
所有的http请求和响应在发送到网络前都要进行加密,相当于在http和tcp之间增加了SSL/TCL 全层。
了解一下
1.摘要算法 md5
2.加密算法:
对称加密:编解码时使用相同的密钥,异或
非对称加密:公钥和私钥
输入一个url访问网站?
- 域名解析:把域名解析成ip地址
1.先检查浏览器缓存
2.本机域名解析
3.DNS请求获取ip
- 网络请求
1.TCP三次握手(tls握手)
2.发送http请求
3.http响应
4.浏览器解析响应报文,渲染页面
5.TCP四次挥手
http常见状态码
1xxs状态码
信息性:服务器正在处理请求
2xxs状态码
请求成功
- 200 OK:请求成功。成功的含义取决于HTTP方法
- 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息
3xxs状态码
重定向
- 302: 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在
Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的 - 303:对当前的请求的响应可以在另一个URI上被找到,而且客户端应该采用GET的方式访问那个链接。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源
- 304:如果客户端在发送GET请求时附上了一个值为Sunday的
If-Modified-Since报头,而客户端所请求的表示在服务器端自星期日(Sunday)以来一直没有改变过,那么服务器可以返回一个304响应 - 307: 请求还没有被处理,因为所请求的资源不在本地:它在另一个URI处。客户端应该向那个URI重新发送请求。
4xxs状态码
客户端出现错误
- 401:这意味着你的登录凭证无效。服务器不知道你是谁,这时,你需要尝试重新登录
- 403:服务器已经理解请求,但是拒绝执行它。与401不同,403知道是你登录了,但是还是拒绝了你。
- 404:请求失败,你请求所希望得到的资源未在服务器上发现。
- 405:客户端试图使用一个本资源
不支持的HTTP方法 - 409:你请求的操作会导致服务器的资源处于一种不可能或不一致的状态
5xxs状态码
服务端错误
- 500:服务器内部错误,服务器遇到了不知道如何处理的情况。
- 503:服务器没有准备好处理请求。常见的原因是服务器因维护或重载而停机。
- 504:网关超时,服务器未能快速的做出反应 参考 小结HTTP状态码
restful API是什么?
REST描述的是在网络中client和server的一种交互的形式,REST不是一种协议本身没有太大的作用,实用的是如何设计 RESTful API(REST风格的接口)
web标准
W3C标准:一系列标准的合集
网页主要由三部分组成:
- 结构:结构化标准主要包括XHTML和XML
- 表现:表现标准语言主要包括CSS
- 行为:行为标准主要包括(如W3C DOM、ECMAScript)
ajax实现原理
XMLHttpRequest对象
XMLHttpRequest 对象是 Ajax 的核心,该对象是一种支持异步请求的技术。简而言之,XMLHttpRequest 对象可以让我们使用 JavaScript 向服务器发起请求并处理响应,而不阻塞用户。
通过 XMLHttpRequest 对象,Web 开发人员可以在页面加载后对页面进行局部更新。
创建流程
- 创建一个 XMLHttpRequest 对象
- 创建一个新的 HTTP 请求,并指定该请求的方法、URL 以及是否为异步请求
- 设置响应 HTTP 请求状态变化的函数
- 发送 HTTP 请求
- 对异步返回的数据进行处理
// 创建 XMLHttpRequest 对象
var xhr
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest()
} else if (window.ActiveXObject) {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
// 创建一个新的请求
xhr.open('GET', 'http://www.example.com', true)
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 监听 HTTP 请求状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var res = xhr.responseText
}
}
// 发送 HTTP 请求
xhr.send()
用es5实现promise
function promise (fn) {
if (typeof this !== 'object') {
throw new TypeError('Promises must be constructed via new');
}
if (typeof fn !== 'function') {
throw new TypeError('Promise constructor\'s argument is not a function');
}
this.state = "pending"; //定义状态
this.msg="";
var process=arguments[0];
var that=this;
process(function(){
that.state="resolve"
that.msg=arguments[0]
},function(){
that.state="reject"
that.msg=arguments[0]
})
return this
}
promise.prototype.then=function(){
constructor:promise
if(this.state == "resolve"){
arguments[0](this.msg)
}else if(this.status=='reject'&&arguments[1]){
arguments[1](this.msg)
}
promise=new this.constructor(function (resolve,reject) {resolve("2")}) //每次调用then之后重新返回一个新的promise实例进行下一步then的调用
// console.log(this)
// console.log(promise)
return promise
}
var mm = new promise(function(resolve,reject){
resolve("1")
})
mm.then(function(res){ //then回调
console.log(res)
}).then(function(res){
console.log(res)
})
列举ES6中新增的一些东西
1.let const
2.模版字符串
3.扩展运算符
4.数值的扩展:isNaN
5.数组的扩展
6.函数的扩展:箭头函数、rest参数
7.对象的扩展:遍历 for in、object.keys;对象的扩展运算符等
8.Symbol
9.Set和Map
10.Promise
11.Class
12.Module
13.async
Set WeakSet Map WeakMap对比
小程序页面传值方式
- 通过
EventChannel传值 getCurrentPages()(页面栈)
Object.freeze()和Object.seal()
Object.freeze():冻结一个对象,冻结后不可修改、删除属性,该对象的原型也不能修改
Object.freeze()过程
1.设置Object.preventExtension(),禁止添加新属性(绝对存在)
2.设置writable为false,禁止修改(绝对存在)
3.设置configurable为false,禁止配置(绝对存在)
4.禁止更改访问器属性(getter和setter)
Object.seal():方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要可写就可以改变
1.设置Object.preventExtension(),禁止添加新属性(绝对存在)
2.设置configurable为false,禁止配置(绝对存在)
3.禁止更改访问器属性(getter和setter)
使用Object.freeze()冻结的对象中的现有属性是不可变的。用Object.seal()密封的对象可以改变其现有属性
Object.create()
使用Object.create()是将对象继承到原型链上,然后可以通过对象实例的__proto__属性进行访问原型链上的属性
script标签中的async和defer
- 没有defer或async属性,浏览器会立即加载并执行相应的脚本,
阻塞后续文档的加载 - async: 表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的
- defer: 加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要
等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前
JS中ready和onload的区别
onload:等待网页资源全部加载完毕;只能执行一次,多次执行会覆盖;ready:等待网页中的DOM结构加载完毕;可执行多次并且不会覆盖;
iframe的优缺点
优点
- 重载页面时不需要重载整个页面,只需要重载页面中的一个框架页
- 技术易于掌握,使用方便,使用者众多,可主要应用于不需搜索引擎来搜索的页面
缺点
- 会产生很多页面,不容易管理
HTTP的请求头都包括哪些?请求方法都有哪些?
http协议报文包括
- 请求报文:请求行(
请求方法和协议版本)、请求头、请求体 - 响应报文:状态行、消息报头、响应正文
请求方法:
OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法HEAD: 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。GETPOSTPUT:向指定资源位置上传其最新内容DELETE:请求服务器删除Request-URL所标识的资源TRACE:回显服务器收到的请求,主要用于测试或诊断CONNECT:预留给能够将连接改为管道方式的代理服务器
请求头
Host:主机地址
Accept:客户端可识别的内容类型列表。
Accept-Encoding:告诉服务器能接受什么编码格式
User-Agent:产生请求的浏览器类型。
Cache-Control:对缓存进行控制
Referer:表示这是请求是从哪个URL进来的
请求头中强制缓存和协商缓存
- 强制缓存:当浏览器去请求某个文件的时候,服务端就在respone header里面对该文件做了缓存配置,
缓存的时间、缓存类型 - 协商缓存:就是强制缓存
失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
get和post的区别
- GET在浏览器回退时是无害的,而POST会再次提交请求
- GET请求会被浏览器主动cache,而POST不会,除非手动设置
- GET产生的URL地址可以被Bookmark,而POST不可以
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
简述跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
代码题
for(var i=0;i<3;i++){
setTimeout((function(){
console.log(i)
})(i),0)
}
//输出0 1 2
var a=10;b=20;c=4
++b+c+a++//输出35
continue和break
typeof null的输出及原因
object
不同的对象在底层都表示为二进制,在javascript中二进制前三位都为0的话会被判断为object类型, null的二进制表示全0,自然前三位也是0,所以执行typeof时会返回“object”
用flex实现一个九宫格
列举几个合并对象的方法,object.assign的特点
- 遍历赋值
Object.assign():将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
call apply bind三者的区别
- call与apply传参不同,apply参数是数组,call和bind是分开传
- bind返回一个新的函数,
调用时才执行;call和apply是立即执行
Promise和async await的区别,运用场景
- Promise是链式调用,在一些复杂的业务场景上不美观
- async/await是基于Promise实现的,不能用于一个普通的回调函数
用localStorage做日志监控
window.dispatchEvent()这个方法来派发一个事件,让window去监听。新实例出来的这个事件会被绑定到window上来监听它的调用,当调用的时候可以拿到setItem的新值,直接赋值就可以
1.document.createEvent() //创建实例
2.event.initEvent() //初始化实例
3.element.dispatchEvent() //触发事件
dispatchEventStroage () {
const signSetItem = localStorage.setItem
localStorage.setItem = function (key, val) {
let setEvent = new Event('setItemEvent')
setEvent.key = key
setEvent.newValue = val
window.dispatchEvent(setEvent)
signSetItem.apply(this, arguments)
}
}
数组哪些方法可以跳出循环
- for循环可以用break
- forEach可以用try...catch来跳出循环
- every可以用return false /return true
- some可以用return true
promise如何中断
git命令行操作,回滚到一个commit并修改,但是不影响其他commit
1.回滚代码
1. git log // 查询要回滚的 commit_id
2. git reset --hard commit_id // HEAD 就会指向此次的提交记录
3. git push origin HEAD --force // 强制推送到远端
2.撤销提交
1. git log // 查找要删除的前一次提交的 commit_id
2. git rebase -i commit_id // 将 commit_id 替换成复制的值
3.放弃某次提交
1. git log // 查找需要撤销的 commit_id
2. git revert commit_id // 撤销这次提交
web端,移动端响应式布局
- 媒体查询
- 百分比
- vw/vh
- rem
- 利用UI框架实现响应式布局
一个页面可以嵌入几个webview
["1", "2", "3"].map(parseInt)的输出结果是什么
[1,NaN,NaN]
原因:
- map方法接收一个
callBack函数,第一个参数是当前处理的元素,第二个参数是索引值 - parseInt是用来解析字符串,将字符串
解析成指定基数的整数 - radix是一个介于
2-36之间的整数,返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回NaN
parseInt(string, radix)
parseInt(‘1’, 0); // radix为0时,使用默认的10进制。
parseInt(‘2’, 1); // radix值在2-36,无法解析,返回NaN
parseInt(‘3’, 2); // 基数为2,2进制数表示的数中,最大值小于3,无法解析,返回NaN
React相关
vue和react有没有相互没有的优点
react render什么时候会执行
state和props数据更新的时候
React最新的两个生命周期
getDerivedStateFromPropsgetSnapshotBeforeUpdate
react和vue怎么做到强制刷新?
this.forceUpdate()
mobx和redux区别
列举React父子组件传值取值的方式
- props
- ref
React key的作用?
用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识
调用 setState 之后发生了什么?
- React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程
- 经过调和过程,React会以相对高效的方式根据新的状态构建React元素树并且着手重新渲染整个 UI 界面。
- 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。
- 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了
按需更新,而不是全部重新渲染。
触发多次setstate,那么render会执行几次
- 多次setState会合并为一次render,因为setState并不会立即改变state的值,而是将其放到一个
任务队列里,最终将多个setState合并,一次性更新页面。 - 所以我们可以在代码里多次调用setState,每次只需要关注当前修改的字段即可 思考setState为什么是异步?
当批量执行state的时候可以让DOM渲染的更快,也就是说多个setstate在执行的过程中还需要被合并
this.setState之后react做了哪些操作?
shouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate
简述一下virtual DOM (虚拟dom)如何工作?
- 当数据发生变化,比如setState时,会引起组件重新渲染,整个UI都会以virtual dom的形式重新渲染
- 然后收集差异也就是diff新的virtual dom和老的virtual dom的差异
- 最后把差异队列里的差异,比如增加节点、删除节点、移动节点更新到真实的DOM上 diff算法相关
简述diff算法
从根结点开始遍历所有节点,将同级的节点进行对比,设置给对应老节点开始-结束的索引,新节点开始-结束的索引,进行遍历,更新位置,或是删除的一个过程
React 中 refs 的作用是什么?
<button ref="myBtn"></button>
- 给元素定义ref属性,后续可以通过 this.refs.myBtn 来获取这个真实DOM对象
- 给组件定义ref属性,后续可以通过 this.refs.myBtn 来获取这个组件的实例对象
<button ref="{ (sl) => { this.myBtn = sl } }"></button>
- 给元素定义ref属性,后续可以通过 this.myBtn 来获取这个真实DOM对象
- 给组件定义ref属性,后续可以通过 this.myBtn 来获取这个组件的实例对象
为什么列表循环渲染的key最好不要用index?
当key值对应的子元素相同时,不删除并更新,只做移动操作;当key值对应的子元素不同,就删除并重新创建,影响性能
什么是状态提升
状态提升,即将两个组件需要共享的数据保存在共同的父组件中,然后子组件通过 props 获取父组件数据
useCallback useMemo
提高性能
useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;并且这两个hooks都返回缓存的值,useMemo返回缓存的变量,useCallback返回缓存的函数。
- useMemo
- useCallBack:通常而言,如果父组件更新了,子组件也会执行更新;我们可以借助useCallback来返回函数,然后把这个函数作为props传递给子组件;这样,子组件就能避免不必要的更新。 useMemo与useCallback使用指南
频繁设置setState优化
react-hooks
react的生命周期有哪些
- componentWillMount
- render
- componentDidMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
useEffect包含的生命周期?
componentDidMount、componentWillUnmount、componentDidUpdate
react-hooks的优点
- useEffect可以让相同逻辑在同一个地方进行处理
- 更容易拆分组件
- 不用考虑this指向
- 更容易复用
react-hooks的Api
使用hooks需要注意的
react的优化方法,提升性能?
- 使用key来帮助React识别列表中所有子组件的最小变化
- 重写shouldComponentUpdate来避免不必要的dom操作
- 组件尽可能进行拆分
props和state的区别
state:用来存储组件内的数据状态,可以通过setState来修改,只存在于有状态组件中
props:父子组件沟通的桥梁,子组件不能直接修改他,可以存在有或者无状态组件中
VUE相关
单页面应用的优缺点
1.优点
- 页面内容改变
不需要重新加载整个页面,获取数据也是异步,不会出现白屏现象 - 良好的前后端分离
- 减轻服务器压力
2.缺点
- 首屏加载慢 解决方案:1.vue-router懒加载 2.使用CDN加速 3.异步加载组件 4.服务端渲染
- 不利于SEO
- 不适合大型项目
mvvm
v-model的原理
一方面modal层通过defineProperty来劫持每个属性,一旦监听到变化通过相关的页面元素更新。另一方面通过编译模板文件,为控件的v-model绑定input事件,从而页面输入能实时更新相关data属性值
vue常用的指令
v-if、v-show、v-for、v-on、v-bind、v-model
vue的生命周期有哪些?vue中props的值是在哪个生命周期拿到的
beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed
vue的计算属性和方法区别
- 不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值,多次访问 getAge 计算属性会立即返回之前的计算结果,而不必再次执行函数
- methods方法,每当触发重新渲染时,调用方法将总会再次执行函数
vue的事件修饰符有哪些
- .prevent
- .stop
vue子组件向父组件传值
prop向下传递,事件向上传递
$emit
route和router的区别
route对象表示当前的路由信息router对象全局路由的实例
路由传值的两种方式
- params
- query
router-view注册
scoped及如何修改公共组件的样式
1.穿透scoped
<style scoped>
外层 >>> 第三方组件 {
样式
}
</style>
2.再定义一个不含有scoped属性的style标签
为什么会出现修改数据,但是页面没有变化的情况?
- Vue 无法检测对象 property 的添加或移除
- Vue 不能检测通过数组索引直接修改一个数组项
- Vue 不能监测直接修改数组长度的变化
- 在异步更新执行之前操作 DOM 数据不会变化
解决方法Vue.set,vm.$set
如何封装一个表单组件
后台做一个面包屑
import和require的区别
vuex,取vuex值的方法有哪些
vuex
- state
- mutations
- getters 加工state成员给外界
- actions:实际提交的是mutation,异步操作
- modules 模块化状态管理
取值方式:
1.
computed:{
count(){
return this.$store.state.count
}
}
2.
import { mapState } from"vuex"
computed:mapState({
count : 'count',
count1 : 'count1'
})
set get
两个互不相干的组件怎么调用对方的方法
$emit $on
nextTick的原理,怎么修改表单数据
nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,