- XSS攻击(Cross-Site Scripting)即跨站脚本攻击:
是一种代码注入攻击。比如在一个网站能输入的地方输入一些恶意脚本,由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,利用这些信息冒充用户向网站发起攻击者定义的请求。 攻击者向有 XSS 漏洞的网站中输入恶意的 HTML 代码,当其它用户浏览该网站时候,该段 HTML 代码会自动执行,从而达到攻击的目的,如盗取用户的 Cookie,破坏页面结构,重定向到其它网站等 。
防御:
利用正则检查输入内容进行过滤,对输入的内容进行转义,比如:
- & 替换 为:
& - < 替换为
<; -
替换为
> - ‘’ 替换为
" - ’ 替换为
' - / 替换为
/
- CSRF攻击(Cross-site request forgery)即跨域请求伪造:
原理:
- 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
- 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
- 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
- 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
- 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行
防御:
CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开。跟验证码类似,只是用户无感知。 服务端给用户生成一个token,加密后传递给用户 用户在提交请求时,需要携带这个token 服务端验证token是否正确。
HTML5和CSS3常问:
MVVM中的双向绑定:
由视图(View)、视图模型(ViewModel)、模型(Model)三部分组成。vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。
1.当一个对象(或变量)的属性改变,那么调用这个属性的地方显示也应该改变,模型到视图(model => view)
2.当调用属性的这个地方改变了这个属性(通常是一个表单元素),那么这个对象(或变量)的属性也会改为最新的值 ,即视图到模型(view => model)
如下通过defineProperty实现双向绑定例子:
PS:加入了 用户输入中文的判断(用户输入中文时,频繁触发 keyup事件,但实际上输入并没有结束。)
语法: Object.defineProperty(obj, prop, descriptor)
obj: 需要被操作的目标对象
prop: 目标对象需要定义或修改的属性的名称
descriptor: 将被定义或修改的属性的描述符
var obj = new Object();
Object.defineProperty(obj, 'name', {
configurable: false,
writable: true,
enumerable: true,
value: '张三'
})
console.log(obj.name) //张三
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>双向绑定</title>
</head>
<body>
手写一个简单双向绑定<br/>
<input type="text" id="model"><br/>
<div id="modelText"></div>
</body>
<script>
var model = document.querySelector("#model");
var modelText = document.querySelector("#modelText");
var defaultName = "defaultName";
var userInfo = {}
model.value = defaultName;
Object.defineProperty(userInfo, "name", {
get: function () {
return defaultName;
},
set: function (value) {
defaultName = value;
model.value = value;
console.log("-----value");
console.log(value);
modelText.textContent = value;
}
})
userInfo.name = "new value";
var isEnd = true;
model.addEventListener("keyup", function () {
if (isEnd) {
userInfo.name = this.value;
}
}, false)
//加入监听中文输入事件
model.addEventListener("compositionstart", function () {
console.log("开始输入中文");
isEnd = false;
})
model.addEventListener("compositionend", function () {
isEnd = true;
console.log("结束输入中文");
})
</script>
</html>
每当通过userInfo.name ="***"; 这样的方式设置对象值得时候,就会触发defineProperty这个里面的set方法。每当通过userInfo.name这个方式获取对象的值得时候就会触发defineProperty这个里面的get方法。
MVC和MVVM:
MVC :
即 Model-View-Controller 的缩写,就是 模型—视图—控制器,也就是说一个标准的Web 应用程式是由这三部分组成的:
View :用来把数据以某种方式呈现给用户
Model :其实就是数据
Controller :接收并处理来自用户的请求,并将 Model 返回给用户
MVC同时也会带来的问题:
1、 开发者在代码中大量调用相同的 DOM API,处理繁琐 ,操作冗余,使得代码难以维护。
2、大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
3、 当 Model 频繁发生变化,开发者需要主动更新到View ;当用户的操作导致 Model 发生变化,开发者同样需要将变化的数据同步到Model 中,这样的工作不仅繁琐,而且很难维护复杂多变的数据状态。
MVVM:
MVVM 由 Model、View、ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
关于同源策略:
目的:出于信息安全考虑。
同源条件:
协议相同 域名相同 端口相同 举例:www.example.com/dir/page.ht… 这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略),同源情况如下:
www.example.com/dir2/other.… example.com/dir/other.h… v2.www.example.com/dir/other.h… www.example.com:81/dir/other.h… www.example.com/dir/page.ht…
不同源的限制范围:
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
- 无法接触非同源网页的 DOM。
- 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)。
允许跨域行为实例:
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
单点登录:
单点登录 SSO 全称 Singn Sign On 。SSO 指在多个应用系统中,用户只需要登录一次用户系统,就可以访问其他互相信任的应用系统。例如:在网易官网登录账户,那么再进入网易邮箱等其他业务的时候会自动登录。另外还有一个好处就是在一定时间内可以不用重复登录账户。
问题:
单点登录出现在二级域名的时候就不用跨域,可以通过cookie来共享登录信息。例如bbb.a.com 和 ccc.a.com 是二级域名。
单点登录出现在跨域里面比如(www.aaa.com 和 www.bbb.com):
一旦跨域就不能通过cookie来共享后台返回的登录信息。
这时就要通过postMessage来传递登录后返回的信息,比如token。得到来自不同域的信息后就可以实现单点登录了。
例子:
在a页面点击登陆过后,b页面直接影藏登录按钮,显示该用户已经登录。就不用再次登陆
a.html页面代码:
<title>A首页</title>
<meta charset="utf-8">
<p>
<button onclick="login();" id="login">同步登录</button>
<p id="msg" style="display: none;">该用户已经登录
<button onclick="localStorage.clear();" id="login">注销</button>
</p>
</p>
<iframe src="http://www.b.com" style="height: 0px;width: 0px;display: none;"></iframe>
<script>
// 是否显示“同步登录”按钮
var tokenData=localStorage.getItem('tokenData')
if(tokenData){
document.getElementById('login').style.display='none';
document.getElementById('msg').style.display='block';
}
// 同步登录
function login(){
let data=JSON.stringify({
msg:'建议以字符串形式传输字符串',
token:'这是从后台而来的token'
})
document.getElementsByTagName('iframe')[0].contentWindow.postMessage(data,'*');
}
// 有消息从父级传来时 存贮 tokenData
window.addEventListener('message',function(e){
if(e.source!=window.parent) return;
localStorage.setItem("tokenData",e.data);
},false);
</script>
b.html页面代码:
<title>B首页</title>
<meta charset="utf-8">
<p>
<button onclick="login();" id="login">同步登录</button>
<p id="msg" style="display: none;">该用户已经登录
<button onclick="localStorage.clear();" id="login">注销</button>
</p>
</p>
<iframe src="http://www.a.com" style="height: 0px;width: 0px;display: none;"></iframe>
<script>
// 是否显示“同步登录”按钮
var tokenData=localStorage.getItem('tokenData')
if(tokenData){
document.getElementById('login').style.display='none';
document.getElementById('msg').style.display='block';
}
// 同步登录
function login(){
let data=JSON.stringify({
msg:'建议以字符串形式传输字符串',
token:'这是从后台而来的token'
})
document.getElementsByTagName('iframe')[0].contentWindow.postMessage(data,'*');
}
// 有消息从父级传来时 存贮 tokenData
window.addEventListener('message',function(e){
if(e.source!=window.parent) return;
localStorage.setItem("tokenData",e.data);
},false);
</script>
各种上传问题:
掘金:
github:
我的关注/
别人的优秀代码:github.com/Bigerfe/fe-…