DOM 总结
25、DOM 事件模型是什么?
- 冒泡和捕获
- 如果这个元素是被点击的元素,那么捕获不一定在冒泡之前,顺序是由监听顺序决定的。
26、事件委托是什么,有什么好处?
事件委托就是利用冒泡原理,将事件绑定到节点的父级节点上,从而触发事件中代码的效果。
事件委托的好处:
1)提高js性能;
2)后续添加的元素同样能触发事件;
代码:
var ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
var el = e.target
while(el.tagName !== 'LI'){
if(el === ul){
el = null
break
}
el = el.parentNode
}
if(el){
console.log('你点击了 li 元素')
}else{
console.log('你点击的不是 li 元素')
}
})
27、移动端的触摸事件了解吗?
touchstart、 touchmove、 touchend、 touchcancel
模拟 swipe 事件:记录两次 touchmove 的位置差,如果后一次在前一次的右边,说明向右滑了。
HTTP 复习:
28、HTTP 缓存怎么做?强制缓存与对比缓存的区别。
已存在缓存数据时,仅基于强制缓存,请求数据的流程如下
已存在缓存数据时,仅基于对比缓存,请求数据的流程如下
我们可以看到两类缓存规则的不同,强制缓存如果生效,不需要再和服务器发生交互,而对比缓存不管是否生效,都需要与服务端发生交互。
两类缓存规则可以同时存在,强制缓存优先级高于对比缓存,也就是说,当执行强制缓存的规则时,如果缓存生效,直接使用缓存,不再执行对比缓存规则。
总结
对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
对于比较缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。
29、Cookie 是什么?Session 是什么?
Cookie
HTTP响应通过 Set-Cookie 设置 Cookie
浏览器访问指定域名是必须带上 Cookie 作为 Request Header
Cookie 一般用来记录用户信息
Session
Session 是服务器端的内存(数据)
Session 一般通过在 Cookie 里记录 SessionID 实现
SessionID 一般是随机数
30、LocalStorage 和 Cookie 的区别是什么?
Cookie 会随请求被发到服务器上,而 LocalStorage 不会
Cookie 大小一般4k以下,LocalStorage 一般5Mb 左右
31、GET 和 POST 的区别是什么?
1)参数。GET 的参数放在 url 的查询参数里,POST 的参数(数据)放在请求消息体里。
2)GET 的参数(url查询参数)有长度限制,一般是 1024 个字符。POST 的参数(数据)没有长度限制(但实际也有4~10Mb 限制)
3)包。GET 请求只需要发一个包,POST 请求需要发两个以上包(因为 POST 有消息体)(扯淡,GET 也可以用消息体)
4)GET 用来读数据,POST 用来写数据,POST 不幂等(幂等的意思就是不管发多少次请求,结果都一样。)
5)安全性。GET 没有 POST 安全(都不安全)
具体介绍见链接 HTTP简要介绍
32、怎么跨域?JSONP 是什么,CORS 是什么,postMessage 是什么。
JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。
是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行 提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。换句话说,JSONP 需要对应接口的后端的配合才能实现。
JSONP文字流程
JSONP请求方:发送请求的浏览器
JSONP响应方:被发送的请求的服务器
1、请求方创建 script,src 指向响应方,同时传上响应方的路径和查询参数
script src = '/路径?callback =' + functionName
2、 响应方根据查询参数 callback,构建形如
${query.callback}.call(undefined,'你要的数据')
,这样的响应3、浏览器收到响应就会执行
${query.callback}.call(undefined,'你要的数据')
4、请求方就知道了他要的数据
约定:
functionName 是一个函数的名字,并且这个名字是随机生成的,形如
var functionName = 'keduoc' + parseInt(Math.random()*100000,10) // keduoc23238
window[functionName] = function(response){
if(response === '你要的数据'){
......
}
}
JSONP的jQuery方式:
$.ajax({
url:"/路径", // 不传查询参数是因为jQuery会自动生成并添加
dataType:"jsonp", // 记得每行结尾的逗号
success: function(response){
if(response === '你要的数据'){
......(函数)
}
}
})
另外:
1)JSONP出现在Ajax之前,主要目的是为解决页面与后端的无刷新交互。
2)JSONP的主要方法是通过动态创建
Access-Control-Allow-Origin
该字段必填。它的值要么是请求时Origin字段的具体值,要么是一个*,表示接受任意域名的请求。
代码部分
请求端整体代码
<!DOCTYPE html>
<html lang="en">
<head>
<title>首页</title>
<link rel = "stylesheet" href = "/style.css">
<meta charset="UTF-8">
</head>
<body>
<h5>您的账户余额是 <span id = "amount">&&&amount&&&</span></h5>
<button id="button">打钱</button>
<script >
button.addEventListener('click',(e) =>{
let script = document.createElement('script');
let functionName = 'keduo' + parseInt(Math.random()*100000,10)
window[functionName] = function (response) {
if (response === '你要的数据') {
amount.innerText = amount.innerText - 1
}
}
script.src = '/pay?callback='+functionName // 注意要加上查询参数 ?callback=functionName 且注意是'...' + functionName
document.body.appendChild(script)
script.onload = function (e) {
e.currentTarget.remove()
delete window[functionName]
}
script.onerror = function (e) {
e.currentTarget.remove()
delete window[functionName]
}
})
</script>
</body>
</html>
请求端的整体代码可以用 jQuery 简化成
<!DOCTYPE html>
<html lang="en">
<head>
<title>首页</title>
<link rel = "stylesheet" href = "/style.css">
<meta charset="UTF-8">
</head>
<body>
<h5>您的账户余额是 <span id = "amount">&&&amount&&&</span></h5>
<button id="button">打钱</button>
<script >
button.addEventListener('click',(e) =>{
$.ajax({
url:"/路径", // 不传查询参数是因为jQuery会自动生成并添加
dataType:"jsonp", // 记得逗号
success: function(response){
if(response === '你要的数据'){
amount.innerText = amount.innerText - 1
}
}
})
})
</script>
</body>
</html>
响应端整体代码
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?\nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('方方说:含查询字符串的路径\n' + pathWithQuery)
if(path === '/'){
var string = fs.readFileSync('./index.html','utf8')
var amount = fs.readFileSync('./db','utf8')
string = string.replace('&&&amount&&&',amount) //将数据库中的数据代替占位符
response.statusCode = 200
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write(string)
response.end()
}else if(path ==='/style.css'){
var string = fs.readFileSync('./style.css','utf8')
response.setHeader('Content-Type', 'text/css;charset=utf-8')
response.write(string)
response.end()
}else if(path === '/main.js'){
var string = fs.readFileSync('./main.js','utf8')
response.setHeader('Content-Type','application/javascript')
response.write(string)
response.end()
}else if(path === '/pay'){
var amount = fs.readFileSync('./db','utf8')
var newAmount = amount - 1
fs.writeFileSync('./db',newAmount)
response.setHeader('Content-Type','application/javascript')
response.write(`${query.callback}.call(undefined,'你要的数据')`)
response.end()
}else{
response.statusCode = 404
response.setHeader('Content-Type','text/html;chatset=utf-8')
response.write('找不到对应的路径,你需要自行修改 index.js')
response.end()
}
})
来源:CSDN
作者:打野蔡文姬
链接:https://blog.csdn.net/weixin_43915673/article/details/104736825