导航
[[深刻01] 执行上下文](https://juejin.im/post/684490...
[[深刻02] 原型链](https://juejin.im/post/684490...
[[深刻03] 继承](https://juejin.im/post/684490...
[[深刻04] 事件循环](https://juejin.im/post/684490...
[[深刻05] 柯里化 偏函数 函数记忆](https://juejin.im/post/684490...
[[深刻06] 隐式转换 和 运算符](https://juejin.im/post/684490...
[[深刻07] 浏览器缓存机制(http缓存机制)](https://juejin.im/post/684490...
[[深刻08] 前端平安](https://juejin.im/post/684490...
[[深刻09] 深浅拷贝](https://juejin.im/post/684490...
[[深刻10] Debounce Throttle](https://juejin.im/post/684490...
[[深刻11] 前端路由](https://juejin.im/post/684490...
[[深刻12] 前端模块化](https://juejin.im/post/684490...
[[深刻13] 观察者模式 公布订阅模式 双向数据绑定](https://juejin.im/post/684490...
[[深刻14] canvas](https://juejin.im/post/684490...
[[深刻15] webSocket](https://juejin.im/post/684490...
[[深刻16] webpack](https://juejin.im/post/684490...
[[深刻17] http 和 https](https://juejin.im/post/684490...
[[深刻18] CSS-interview](https://juejin.im/post/684490...
[[深刻19] 手写Promise](https://juejin.im/post/684490...
[[深刻20] 手写函数](https://juejin.im/post/684490...
[[react] Hooks](https://juejin.im/post/684490...
[[部署01] Nginx](https://juejin.im/post/684490...
[[部署02] Docker 部署vue我的项目](https://juejin.im/post/684490...
[[部署03] gitlab-CI](https://juejin.im/post/684490...
[[源码-webpack01-前置常识] AST形象语法树](https://juejin.im/post/684490...
[[源码-webpack02-前置常识] Tapable](https://juejin.im/post/684490...
[[源码-webpack03] 手写webpack - compiler简略编译流程](https://juejin.im/post/684490...
[[源码] Redux React-Redux01](https://juejin.im/post/684490...
[[源码] axios ](https://juejin.im/post/684490...
[[源码] vuex ](https://juejin.im/post/684490...
[[源码-vue01] data响应式 和 初始化渲染 ](https://juejin.im/post/684490...
[[源码-vue02] computed 响应式 - 初始化,拜访,更新过程 ](https://juejin.im/post/684490...
XSS
- XSS ( Cross Site Script ) 跨站脚本攻打
- Cross Site Script 本来是缩写为CSS,为了辨别层叠样式表css,改写为XSS
- 原理:XSS攻打是指攻击者在网站上注入歹意的客户端代码,通过 <font color=red>歹意脚本</font> 对客服端网页进行篡改,从而在用户浏览网页时,对用户浏览器就行管制,或者获取用户隐衷数据一种攻击方式
- 歹意脚本:次要指 <font color=red>javascrip代码</font>,有时也指 <font color=red>html</font> 和 <font color=red>flash</font>
攻击方式:有多种,独特的特色是:窃取用户的隐衷数据 - 攻打类型:能够分为三类,<font color=red>反射型(非长久型)</font>,<font color=red>贮存型(长久型)</font>,<font color=red>基于DOM</font>
危害:
- 利用虚伪的输出表单,骗取用户的个人信息
- 利用脚本获取用户的cookie
- 显示伪造的图片和文章
反射型(非长久型)XSS攻打
- 反射型 XSS 只是简略地把用户输出的数据 “反射” 给浏览器,这种攻击方式往往须要攻击者诱使用户点击一个歹意链接,或者提交一个表单,或者进入一个歹意网站时,注入脚本进入被攻击者的网站。
贮存型(长久型)XSS攻打
- 存储型 XSS 会把用户输出的数据 "存储" 在服务器端,当浏览器申请数据时,脚本从服务器上传回并执行。这种 XSS 攻打具备很强的稳定性。
基于DOM的XSS攻打
- 基于 DOM 的 XSS 攻打是指通过歹意脚本批改页面的 DOM 构造,是纯正产生在客户端的攻打。
进攻XSS攻打
<font color=red>设置 httpOnly 阻止通过script脚本获取cookie</font>
- 如
Document.cookie属性
,XMLHttpRequest对象
,Request API
XMLHttpRequest获取cookie
- 通过xhr.getResponseHeader('Set-Cookie') // null,不能获取cookie
- 通过xhr.getAllResponseHeader()获取所有的simple response header,并不包含Set-Cookie字段
留神:这两种办法都只能获取simple response heade,而不能获取Set-Cookie字段
- <font color=red>上面会详解介绍XMLHttpRequest</font>
- 如
过滤查看:
- 对input,textares,form表单等做特殊符号的过滤查看
- HtmlEncode:某些状况下,不能对用户数据进行严格过滤,须要对标签进行转换
- JavaScriptEncode
(1) HtmlEncode:对html标签进行转换< -------------------------- <> -------------------------- >& -------------------------- &'' ------------------------- "空格 -----------------------  (2) JavascriptEncode:对js一些特殊符号进行转码" ------------------------ \"\n ----------------------- \\n\r ----------------------- \\r
CSRF
- CSRF( Cross Site Request Forgery ) 跨站申请伪造
forgeries:伪造品的意思
- <font color=red>CSRF是一种劫持受信赖用户向服务器发送非预期申请的攻击方式</font>
原理:
次要是通过获取用户在指标网站的cookie,骗取指标网站的服务器的信赖,在用户曾经登录指标站的前提下,拜访到了攻击者的钓鱼网站,攻击者间接通过 url 调用指标站的接口,伪造用户的行为进行攻打,通常这个行为用户是不知情的。
- <font color=red>即获取了cookie,就能够做很多事件:比方以你的名义发送邮件、发信息、盗取账号、购买商品、虚构货币转账等等</font>
案例:CSRF攻打的思维:(外围2和3)1、用户浏览并登录信赖网站(如:淘宝)2、登录胜利后在浏览器产生信息存储(如:cookie)3、用户在没有登出淘宝的状况下,拜访危险网站 // 留神:如果该cookie在没有设置过期工夫或者为null,默认是会话工夫session-cookie,敞开浏览器后cookie会被革除// Expires,Max-Age能够设置cookie的过期工夫// 所以这里强调了是没有登出的状况,就有cookie被获取的危险// 如果cookie设置了具体的过期工夫,有效期内都可能被获取4、危险网站中存在恶意代码,代码为发送一个歹意申请(如:购买商品/余额转账)// 该申请,携带刚刚在浏览器产生的信息(cookie),进行歹意申请5、淘宝验证申请为非法申请(辨别不出是否是该用户发送)// 用HTTP中的header头中的 Refer 来预防// refer 能够查看申请源,只有非法的申请起源服务器才予以响应6、达到了歹意指标
预防CSRF攻打
<font color=red>验证码:</font>被认为是反抗CSRF攻打最简洁无效的进攻办法
- CSRF往往是在用户不知情的状况下构建了网络申请,而验证码会强制用户必须与利用进行交互能力实现最终的申请
- 留神:出于用户思考,不能给网站的所有操作都加上验证码,所以验证码只能作为进攻CSRF的辅助伎俩
<font color=red>Referer查看</font>
- HTTP中有Refer字段,示意申请起源地址,通过Refer能够查看申请是否来自非法的源,服务器只对非法的源予以响应
- 2021/4/7更正 => referer查看,而不是refer,留神单词拼写
- 2021/6/21更正 =>
referer
是Referer
<font color=red>token</font>
- CSRF次要就是获取cookie,所以要进攻的话,就须要在申请中退出攻击者不能伪造的信息,并且该信息不能保留在cookie中
- 能够在 HTTP 申请中以参数的模式退出一个随机产生的 token,并在服务器端建设一个拦截器来验证这个 token,如果申请中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻打而回绝该申请。
温习
cookie
- cookie是服务器保留在浏览器的一小段文本信息,大小不超过4KB,每次申请都会携带cookie
- cookie次要用来分辨两个申请知否来自同一个浏览器,和存储一个状态信息:如用户偏好色彩,字体大小等
- 浏览器能够设置不承受cookie,也能够设置不向浏览器发送cookie
window.navigator.cookieEnabled 返回一个布尔值,示意浏览器是否关上cookie性能
document.cookie 返回以后网页的cookie
- 单个域名设置的cookie不应该超过30个,大小不超过 4KB
- <font color=red>共享cookie的条件:域名和端口必须一样,不要求协定雷同</font>
- <font color=red>cookie的产生:cookie由HTTP协定生成,也次要是供HTTP协定应用</font>
HTTP回应:cookie的生成
- 生成cookie:服务器通过设置HTTP回应头信息中,Set-Cookie 字段来保留cookie
- HTTP回应头信息中,能够蕴含
多个 Set-Cookie 字段
- 除了 cookie 的值,Set-Cookie 还能够附加
cookie的属性,能够蕴含多个属性,没有秩序要求
HTTP/1.0 200 OKContent-type: text/htmlSet-Cookie: yummy_cookie=chocoSet-Cookie: tasty_cookie=strawberrySet-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly// Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly 多个属性,没有秩序要求[page content]
服务器如何批改曾经存在的cookie
- 必须满足四个条件:cookie的 <font color=red>key,domain,path,secure</font> 都匹配
只有有一个属性不同,都会生成全新的cookie
Set-Cookie: key1=value1; domain=example.com; path=/blogSet-Cookie: key1=value2; domain=example.com; path=/// 下面因为path不一样,就设置了一个全新的cookie// 下次发动申请时,会同时发送两个cookie// 发动申请时,发送的cookie => Cookie: key1=value1; key1=value2// 留神:两个cookie同名,然而越准确的cookie排在越后面
删除一个现存cookie的惟一办法
- 设置Expires属性为一个过期的工夫
HTTP申请:cookie的发送
浏览器在向服务器发送HTTP申请时,每个申请都会携带上cookie
- (即浏览器把之前服务器保留在浏览器上的cookie再发回服务器)
- <font color=red>发送时应用 Cookie 字段</font>
- <font color=red>生成时应用 Set-Cookie 字段</font>
<font color=red>Cookie字段能够蕴含多个cookie,应用 ; 号宰割</font>
GET /sample_page.html HTTP/1.1Host: www.example.orgCookie: yummy_cookie=choco; tasty_cookie=strawberry
服务器收到浏览器发来的cookie时,有两点无奈晓得
- Cookie的各种属性:Expires,Max-Age,Domain,Path,Secure,HttpOnly
- 哪个域名设置的cookie,一级域名设置的,还是二级域名设置的
Cookie的属性
Expires,Max-Age
Expires属性:指定一个具体的过期工夫,UTC格局
- 能够应用
Date.prototype.toUTCString()
进行格局转换 - 如果不设置Expires属性,或者设置null,该cookie就是session-cookie,只在会话工夫内无效,即敞开浏览器窗口,以后session完结,cookie就会被删除
- 能够应用
- Max-Age属性:从当初开始cookie存在的秒数。
60*60*24*365一年
- 同时存在Expires和Max-Age时,Max-Age优先
Domain,Path
Domain:指定浏览器收回HTTP申请时,哪些域名要附带这个Cookie
- 如果没有指定该属性,将其设置为URL的一级域名
Path:指定浏览器收回HTTP申请时,哪些门路要附带这个cookie
- 只有浏览器发现,Path属性是HTTP申请门路的结尾一部分,就会在头信息中携带这个cookie
Secure,HttpOnly
- Secure:指定只有在加密协议HTTPS下,能力将这个cookie发送到服务器
HttpOnly:指定该cookie,无奈通过脚本拿到
- <font color=red>Document.cookie属性,XMLHttpRequest对象, Request API 都拿不到该cookie</font>
Document.cookie读写cookie
Document.cookie读取:读取全副 Document.cookie写入:一次只能写入一个,写入不是笼罩,而是增加 - Document.cookie的读写差别与HTTPT通信格局无关:
发送:HTTP申请发送cookie,Cookie字段,一次能够设置多个cookie,用分号隔开 生成:Http响应生成cookie,Set-Cookie字段,一次设置一个cookie,但能够有多个Set-Cookie字段
XMLHttpRequest
- const api = new XMLHttpRequest()
- api.open(method, url, async)
- api.send(body)
- api.setRequestHeader()
- api.getResponseHeader()
// 获取参数对应的 simple response header,参数必须在simple response header范畴内
- api.getAllResponseHeader()
// 获取所有 simple response header
- api.onreadystatechange()
- api.onload()
- api.onprogress()
// 下载进度
- api.upload.onprogress()
// 上传进度信息
- api.setRequestHeader(name, value)
- api.responseType
// text, document, json, blob, arrayBuffer
- api.timeout
- api.abort()
// 终止申请
api.withCredentidals
// 一个布尔值,示意跨域申请时,是否能够携带认证信息,如cookie
const api = new XMLHttpRequest()
初始化HTTP申请参数(url,http办法等),但并不发送申请,供 send() 办法应用
api.open(method, url, async, username, password)
method:HTTP申请的办法GET, POST, HEAD
url:申请的地址
async:是否异步,默认是true,即异步的发送申请
// false:同步,对send办法的调用将阻塞,直到响应齐全承受
// true或者省略:异步,且通常须要调用 onreadystatechange() 办法(2) api.send()
发送一个http申请,申请参数写在send办法中
api.send(body)
get申请: 参数能够写在open()办法中
post申请:参数卸载send()办法中(3) api.setRequestHeader()
指定一个HTTP申请的头部(申请头),只有在readyState为 1 时能力调用
api.setRequestHeader(name, value)
name: key
value:value
留神:setRequestHeader()办法能够屡次调用,最终的值不是笼罩override而是追加append
留神:setRequestHeader()办法只有在 readyState = 1 时能力调用,即open()之后send()之前(4) api.getResponseHeader()
返回指定的HTTP响应头部的值(响应头)
(5) api.abort() //abort:停止的意思
- 勾销以后响应,敞开连贯并且完结任何未决的网络流动
- api.abort()将readyState重置为0
利用:如果申请用了太长的工夫,而且响应不在必要时,能够调用这个办法
(6) api.onreadystatechange()
- api.onreadystatechange()但 readyState = 3 时能够调用屡次
留神:onreadystatechange都是小写,而readyState是驼峰写法
readyState状态:
- UNSENT ------------------ xhr对象胜利结构,open()办法未被调用
- OPEND ------------------- open()办法被调用,send()办法还未被调用,setRequestHeader()能够被调用
- HEADERS_RECEIVED -------- send()办法被调用,响应头和响应状态曾经返回
- LOADING ----------------- 响应体(response entity body)正在下载中,此状态下api.response可能曾经有了响应数据
DONE -------------------- 整个数据传输过程完结,不论本次申请是胜利还是失败
(7) api.onload()
- api.onload()申请胜利时触发,此时 readyState = 4
- 申请胜利的回调有两个:
- readyState===4时的api.onreadystatechange()
- api.onload()办法
api.onload = function () {
//如果申请胜利
if(api.status == 200){
//do successCallback
}
}
留神:status===200是有坑的,因为协商缓存返回的状态码是304,申请也是胜利的申请,所以上面的判断跟欠缺
api.onload = function() {
if((api.status>=200 && api.status < 300) || api.status === 304) {// do successCallback
}
}(8) api.timeout
- api.onload()办法
api.timeout用来设置过期工夫
问题1:申请的开始工夫怎么确定?是api.onloadstart事件触发的时候,也就是api.send()调用的时候
解析:因为api.open()只是创立了链接,当并没有真正传输数据,只有调用api.send()时才真正开始传输
问题2:什么时候是申请完结?
解析:api.loadend事件触发时完结(9) api.onprogress() 下载进度信息
(10) api.upload.onprogress = function(e) { 上传进度信息
if ( e.lengthComputable ) {const present = e.loaded / e.total * 100;
}
}1.
问题1:如何获取response
提供三个属性来获取response:( api.response ) 和 ( api.responseText ) 和 ( responseXML )
api.responseText --- api.responseType='text'、''、不设置时,xhr对象上才有此属性,此时能力调用
api.response --- responseType为""或"text"时,值为"";responseType为其余值时,值为 null2.
问题2:api.responseType有哪些类型
api.responseType类型有:text, document, json, blob, arrayBuffer
api.getReponseHeader() 和 api.getAllResponseHeader()
- api.getResponseHeader()获取参数指定的 simple response header
- api.getAllResponseHeader() 获取所有 simple resopnse header
- <font color=red>留神:这两个办法都不能获取Set-Cookie,无论是同域还是跨域</font>
<font color=red>留神:对于跨域申请,客户端只能获取simple response header 和 Access-Control-Expose-Headers</font>
simple response header:
- Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma
Access-Control-Expose-Headers:
只在跨域申请时的响应头中存在,示意服务端容许裸露给客服端的headers
- 同域申请的响应中不蕴含该字段
- expose:是裸露的意思
- 总结:getAllResponseHeader()只能拿到限度以外的response header, getResponseHeader()的参数也必须是限度以外的参数,否则会Refused to get unsafe header的谬误
api.withCredentials
<font color=red>api.withCredentials一个布尔值,示意跨域申请时,是否能够携带认证信息,默认是false即不容许携带</font>
- 比方 cookie
留神:在同域申请时,cookie会在申请头中主动携带,然而在跨域申请时,并没有主动携带,起因是:在CORS规范中做了规定,默认状况下,浏览器在发送跨域申请时,不能发送任何认证信息(credentials)如"cookies"和"HTTP authentication schemes"。除非xhr.withCredentials为true
跨域申请:所以跨域申请时
- 客户端:
api.withCredentials = true 设置为true
- server端(响应头):
Access-Control-Allow-Credentials:true
- 客户端:
案例
get申请go() { console.log('1111111111'); const api = new XMLHttpRequest(); api.open('GET', ----- 初始http申请参数,申请形式,url, 是否异步 'https://bing.ioliu.cn/v1/rand?type=json', true); api.responseType = 'text'; ------ 文本格式的响应 api.timeout = 5000; ---- 申请过期工夫 api.setRequestHeader('Content-type', 'application/json'); ----- 必须在open()后,send()前设置 api.onreadystatechange = function() { ------ readyState扭转时触发 if ( api.readyState === 4 && this.status === 200) { ---- this指的是api实例 console.log(JSON.parse(this.responseText)) ------ this.response也能拿到同样的数据 } } // 除了在api.onreadystatechange指指定的会调中判断readyState===4,也能够间接在onload中触发 // 两种办法都能够 // 只判断200状态码不欠缺,应该判断 2xx 或者 304 则申请胜利 api.onload = function() { if ( api.status >= 200 && api.status < 300 || api.status === 304 ) { console.log(JSON.parse(api.responseText), 'onload在申请胜利时触发'); } } api.send(); ---- 发送数据}
面试精简 https://juejin.im/post/684490...
https://juejin.im/post/684490...
https://juejin.im/post/684490...
美团 https://juejin.im/post/684490...
知乎 https://zhuanlan.zhihu.com/p/...
XMLHttpRequest https://segmentfault.com/a/11...
我的简书 https://www.jianshu.com/p/729...