JS Web API 网页操作的API(w3c标准)
js基础知识是ECMA262规定的语法,js基础知识是JS Web API的基础,两者结合才能真正使用
DOM
(1)、property:指的是html 标签自带的属性,比如input 的value,id, style,className这些特有的属性,也就是说在w3c标准里面有提到的属性。使用xx.属性进行更改,通常来讲,更改互相影响(value除外)。property 是有类型的,例如Bollean,number,string等
<input type="checkbox"> // 默认不选中
<script type="text/javascript">
const checkbox = document.querySelector('input');
checkbox.checked= false; //实际效果不选中 设为不选中
</script>
(2)、attribute:指的是html标签上面的所有属性,包括自定义属性,比如:data属性,mydata属性,date属性。使用setAttribute添加。attribute 只能是string,而没有其他类型
<input type="checkbox"> // 默认不选中
<script type="text/javascript">
const checkbox = document.querySelector('input');
checkbox.setAttribute('checked', false) // 实际效果选中 因为把false当成了‘false’也就是true
</script>
(3)、设置property和attribute都可能引起dom重新渲染,property 在js机制中避免一些重复的dom渲染,attribute改变html结构了都会导致dom重新渲染,所以最好用property (4)、DOM性能 DOM操作非常昂贵,避免频繁的dom操作,将频繁操作改为一次性操作 (5)、对DOM查询做缓存
// 缓存DOM查询结果,缓存length 只查询一次dom
const pList = document.querySelectorAll('p');
const length = pList.length;
for(i=0; i<length; i++){
console.log(i)
}
const listNode = document.querySelector('p');
// 创建虚拟的节点对象 文档片段,此时还没有插入到DOM结构中
const fragment = document.createDocumentFragment();
for(let i = 0; i<10; i++){
const li = document.createElement('li');
li.innerHTML = `${i}哈哈哈哈哈哈`
// 先插入到文档片段中
fragment.appendChild(li);
}
// 都完成后,再统一插入DOM结构
listNode.appendChild(fragment)
BOM
// 浏览器开发商
const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome')>-1;
事件绑定
1、事件捕获阶段
先捕获,事件从最上一级标签html开始往下查找,直到捕获到事件目标(target)
2、事件冒泡阶段
再冒泡,事件从事件目标(target)开始,往上冒泡直到页面的最上一级html标签。一般响应事件函数在这个阶段
3、事件代理就是利用事件冒泡的原理,把事件绑定到父元素上,然后判断target是否为目标子元素,如果是响应事件函数
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, event => {
const target = event.target
if (selector) {
// 代理绑定
if (target.matches(selector)) {
fn.call(target, event)
}
} else {
// 普通绑定
fn.call(target, event)
}
})
}
// 普通绑定
const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', function (event) {
// console.log(event.target) // 获取触发的元素
event.preventDefault() // 阻止默认行为
alert(this.innerHTML)
})
// 代理绑定
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', 'a', function (event) {
event.preventDefault()
alert(this.innerHTML)
})
4、 element.addEventListener(event, function, useCapture)
useCapture 默认 不写 false 事件句柄在冒泡阶段执行
useCapture true 事件句柄在捕获阶段执行
ajax
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
ajax的实现:用XMLHttpRequest或新的Fetch API与网页服务器进行异步资料交换
ajax 是浏览器发送的请求 传递的都是字符串
function ajax(url) {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true) // true异步 false同步
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(
JSON.parse(xhr.responseText)
)
} else if (xhr.status === 404 || xhr.status === 500) {
reject(new Error('404 not found'))
}
}
}
xhr.send(null)
})
return p
}
const url = '/data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err => console.error(err))
跨域
1、同源策略
浏览器为了安全所有有了同源策略,ajax请求时浏览器要求当前网页和server端必须同源,协议,域名、端口必须一致。 所有的跨域都必须经过server端的允许配合,否则浏览器有漏洞
ajax跨域请求,其实这个跨域请求是发送成功了的,服务器也有返回值,只是浏览器禁止js去读取返回值的内容
2、JSONP jsonp不是真正的ajax
<script>
window.abc = function (data) {
console.log(data)
}
</script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
// 请求到脚本之后紧接着执行脚本 此时window上已经有abc函数,执行脚本中的abc函数就可以把data打印出来
3、后端配置 CORS 规则以允许该域名跨域 response的header的CORS属性 4、webpack-dev-server 配置 proxy
http
(1)、常见状态码
200 成功
301永久重定向(配合location,浏览器自动处理)
302临时重定向(配合location,浏览器自动处理)
500 服务器错误
504 网关超时
(2)、请求头 request header
Accept 浏览器可接受的数据格式 属性的值可以为一个或多个MIME类型的值(描述消息内容类型的因特网标准, 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据)
Accept-Encoding 浏览器可接受的压缩格式 如 gzip
Accept-languange 浏览可接受的语言 如 zh-CN
(3)、返回头 response header
Content-type: 返回的数据格式 如 application/json
Content-length:返回数据的大小 多少字节
Content-Encoding: 返回数据的压缩格式 如gzip
http缓存
主要缓存get请求,html和数据一般不缓存
(1)、强制缓存 cache-control
强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,http状态码为200。这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存,所以Ctrl + F5一顿操作之后就好了。 跟强制缓存相关的header头属性有(Pragma/Cache-Control/Expires)
(2)、协商缓存 last-modified和etag,304状态码
当第一次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商,与服务器端对比判断资源是否进行了修改更新。如果服务器端的资源没有修改,那么就会返回304状态码,告诉浏览器可以使用缓存中的数据,这样就减少了服务器的数据传输压力。如果数据有更新就会返回200状态码,服务器就会返回更新后的资源并且将缓存信息一起返回。跟协商缓存相关的header头属性有(ETag/If-Not-Match 、Last-Modified/If-Modified-Since)请求头和响应头需要成对出现
强制刷新:强制缓存协商缓存 都失效
手动刷新:强制缓存失效 协商缓存有效
正常操作:强制缓存协商缓存 都有效
浏览器缓存 存储
1、cookie
存储容量小,最大4kb,http请求是会发送到服务端,增加请求数据量,只能用document.cookie = ''来修改,太过简陋
2、localStorage
数据会永久存储,除非手动或代码删除,每个域名下各自存储。一般用这个多些
3、sessionStorage 数据只会存在于当前会话,浏览器标签页关闭则清空,每个域名下各自存储
网页的渲染
1、根据HTML代码生成DOM Tree
2、根据css代码生成cssom
3、将DOM Tree和cssom整合生成renderTree
4、不是读完DOM结构才渲染 是一边读一边渲染
5、css加载放到头部
6、加载js会阻塞DOM渲染 所以把js放在body里最后
7、img加载不会阻塞DOM渲染
8、window.onload 等所有资源都加载完成再处理
9、window.DOMContentLoaded 图片资源可以不加载成功就处理
10、合理运用懒加载提升性能
11、防抖和节流提升向能
xss 跨站脚本攻击
xss 跨站脚本攻击 常见邮箱里 有段链接 链接里有发送恶意请求的链接,这种只要邮箱里有文本校验把 <script>转译掉即可,就不能发送请求了。比如收割cookie
xsrf 跨站请求伪造
xsrf 跨站请求伪造攻击 常见邮箱里 有段链接是B网站的链接,点了以后B网站onload的时候发送伪造的删除邮箱邮件的操作,如果邮箱没有token校验就会成功。 添加了token校验,B网站拿不到邮箱的token,因为localstorage和session都有域名保护,其他域名拿不到。就无法伪造token,放到接口里发送,就无法攻击