目标:
能够知道什么是同源策略和跨域
能够知道什么是JSONP
能够知道JSONP的实现原理
能够知道防抖和节流的概念
1.什么是同源
如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源
2.什么是同源策略
同源策略是浏览器提供的一个安全功能
概念:限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互
用于隔离潜在恶意文件的重要安全机制
通俗:浏览器规定,A网站的JS,不允许和非同源的网站C之间,进行资源的交互
1 无法读取非同源网页的Cookie LocalStorage和IndexDB
2 无法接触非同源网页的DOM
3 无法向非同源地址发送Ajax请求
1.2跨域
1.什么是跨域
同源是指两个URL的协议,域名和端口都相同,反之就说跨域
出现跨域的根本原因:浏览器的同源策略不允许非同源的URL之间进行资源的交互
2.浏览器对跨域请求的拦截
跨域请求可以正常发起
网页------------------>web
同<------------------
策 浏览器能正常接收
到跨域响应的数据
注意:浏览器允许发起跨域请求,但是,跨域请求回来,会被浏览器拦截(同策),无法获取页面
3.如何实现跨域数据请求
现如今,实现跨域数据请求,主要两种解决方案,JSONP和CORS
JSONP:出现的早,兼容性好(兼容低版本IE)。缺点只支持GET,不支持POSR
CORS:出现的较晚,是W3C标准,属于跨域Ajax请求的根本方案.支持GET和POSR.
缺点不兼容低版本的浏览器(ie)
2.1什么是JSONP
JSONP是JSON的一种使用模式,可用于解决主流浏览器的跨域数据访问的问题
2.2JSONP的实现原理
由于浏览器同源策略的限制,网页中无法通过Ajax请求非同源的接口数据。
但是<script>标签不受浏览器同源策略的影响,可以通过src属性,请求非同源的JS脚本
实现原理:通过<script>标签的src属性,请求跨域的数据接口,并通过函数调用的形式
接收跨域接口响应回来的数据
2.3自己实现一个简单的JSONP
定义一个success回调函数
<script>
function success(data) {
console.log('JSONP响应回来的数据是: ');
console.log(data);
}
</script>
通过<script>标签,请求接口数据:
<script src="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=success&name=ls&age=30">
</script>
2.4 JSONP的缺点
由于JSONP是通过<scirpt>标签的src属性,来实现跨域数据获取的,JSONP只支持GET数据请求
不支持POST请求
注意:JSONP和Ajax之间没有任何关系,不能把JSONP请求数据的方式叫做Ajax,
因为JSONP没有用到XMLHttpREquest这个对象
2.5jQuery中的JSONP
jQuery提供的$.ajax()函数,除了跨域发起真正的Ajax数据请求之外,还能够发起JSONP数据请求
默认情况下,使用jQuery发起JSONP请求,会自动携带一个callback=jQueryxxx的参数,
jQueryxxx是随机生成的一个回调函数名称
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',
//代表我们发起jsonp请求
//如果要使用$.ajax()发起JSONP请求,必须指定datatype为jsonp
dataType: 'jsonp',
success: function (res) {
console.log(res);
}
})
2.6自定义参数及回调函数名称
在使用jQuery发起JSONP请求时,如果要定义JSONP的参数以及回调函数名称
可以通过如下两个参数来指定
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',
//代表我们发起jsonp请求
//如果要使用$.ajax()发起JSONP请求,必须指定datatype为jsonp
dataType: 'jsonp',
//发送到服务器的参数名称,默认值为callback
jsonp: 'cb',
//自定义的回调函数名称,默认值为jQueryxxx格式
jsonpCallback: 'abc',
success: function (res) {
console.log(res);
}
})
2.7jQuery中JSONP的实现过程
jQuery中的JSONP,也是通过<script>标签的src属性实现跨域数据访问的,
jQuery采用的是动态创建和移除<script>标签的方式,来发起JSONP数据请求
在发起JSONP请求的时候,动态向<header>中append一个<script>标签
在JSONP请求成功以后,动态向<header>中移除刚才append进去的<script>标签
3.案例-淘宝搜索
3.1要实现的UI效果
3.2获取用户输入的搜索关键词
为了获取到用户每次按下键盘输入的内容,需要监听输入框的keyup事件,示例以下
$('#ipt').on('keyup', function () {
var keywords = $(this).val().trim()
// trim() 去除两边的空格 val获取的文本输入框的内容
if (keywords.length <= 0) {
return
}
})
3.3封装getSuggestList函数
$.ajax({
url: 'https://suggest.taobao.com/sug?q=' + kw,
dataType: 'jsonp',
success: function (res) {
console.log(res)
}
})
3.4 渲染建议列表的UI结构
1.定义搜索建议列表
<!-- 搜索建议列表 -->
<div id="suggest-list">
</div>
2.定义模板结构
<!-- 模板结构 -->
<script type="text/html" id="tpl-suggestList">
<!-- id是为了方便获取 -->
{{each result}}
<!-- 循环 -->
<!-- 搜索建议项 -->
<div class="suggest-item">{{$value[0]}}</div>
{{/each}}
3.定义渲染模板结构的函数
if (res.result.length <= 0) {
return $("#suggest-list").empty().hide()
// 如果没有返回的数据 就清空 隐藏
}
var htmlStr = template('tpl-suggestList', res)
$('#suggest-list').html(htmlStr).show()
}
4.搜索关键词为空时隐藏搜索建议列表
3.5 输入框的防抖
1.什么是防抖
防抖策略(debounce)是当事件被触发后,延迟n秒后再执行回调,
如果在这n秒内事件又被触发了,则重新计时
2.防抖的应用场景
用户输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求
这样可以有效减少请求次数,节约请求资源;
3.实现输入框的防抖
//1.防抖动的timer
var timer = null
// 2.定义防抖的函数
function debounceSearch(kw) {
var timer = setTimeout(function () {
//发起JSONP请求
getSuggestList(kw)
}, 500)
}
$('#ipt').on('keyup', function () {
//3 在触发keyup事件 立即清空timer
clearTimeout(timer)
//省略
debounceSearch(keywords)
//获取keywords的内容 如果不是空的 就调用函数 来到搜索键
})
3.6 缓存搜索的建议列表
1.定义全局缓存对象
// 缓存对象
var cacheObj= { }
2.将搜索结构保存到缓存对象中
//渲染建议列表
function renderSuggestList(){
//省略其他代码
//将搜索的结构,添加到缓存对象中
//1.获取到用户输入的内容 当作键
var k = $('#ipt').val().trim()
// 2.需要将数据作为值,进行缓存
cacheObj[k] = res
}
3.有限从缓存中获取搜索建议$('#ipt').on('keyup', function () {
//省略
//判断缓存中是否有数据
if (cacheObj[keywords]) {
return renderSuggestList(cacheObj[keywords])
}
debounceSearch(keywords)
//获取keywords的内容 如果不是空的 就调用函数 来到搜索键
})
4.1什么是节流
节流策略(throttle),顾名思义,可以减少一段时间内事件的触发频率
4.2节流的应用场景
鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
懒加载时要监听计算滚动条的位置,但不必每次滑动到触发
可以降低计算的频率,而不浪费cpu的资源
4.3节流案例 - 鼠标跟随效果1.渲染UI结构并美化样式
UI结构
<img src="./angel.gif" alt="" id="angel" />
html,body{
margin:0;
padding:0;
overflow:hidden;
}
#angel{
position:absolute;
}
2.不使用节流时实现鼠标跟随效果
$(function () {
// 1.获取到图片
var angel = $('#angel')
// 2.绑定 mousemove事件
$(document).on('mousemove', function (e) {
// 3.设置图片的位置
$(angel).css('top', e.pageY + 'px').css('left', e.pageX + 'px')
})
})
3.节流阀的概念
上一个人使用完毕后,需要将红灯重置为绿灯,表示下一个可以使用卫生间
下一个人使用卫生间之前,需要先判断控制灯是否为绿灯,来知道是否上卫生间
节流阀为空,表示可以执行下次操作;不为空,表示不能执行下次操作
当前操作执行完,必须将节流阀重置为空,表示可以执行下次操作了
每次执行操作前,必须先判断节流阀是否为空
4.使用节流优化鼠标跟随效果
$(function () {
var angel = $('#angel')
// 步骤1.定义节流阀
var timer = null
$(document).on('mousemove', function (e) {
//步骤3 判断节流阀是否为空 不为空直接ruturn
if (timer) {
return
}
// 步骤3开启延时器
timert = setTimeout(function (param) {
$(angel).css('top', e.pageY + 'px').css('left', e.pageX + 'px')
}, 16)
timer = null //清空节流阀 方便下次开启延时器
})
})
4.4总结防抖和节流的区别
防抖:如果事件被频繁触发,防抖能保证只有最有一次触发生效!前面N多次的触发都被忽略
节流:如果事件被频繁触发,节流能够减少事件触发的频率,因此,节流是有选择性执行一部分事件