今天是我们最后一天ajax的学习,这次学完总可以去vue了吧,我不信还有什么拦路石,先不说其他的先看看今天的内容。

1.

首先是同源策略,什么叫做同源?

如果两个页面的协议、域名、端口都相同的话,我们将这两个页面为同源。

那么什么同源策略呢?

是浏览器提供的一个安全功能,如果说两个页面不同源,那么A网站就无法读取B网站的cookie、localstorage、indexdb等;无法接触B网站的DOM;无法向B网站发送ajax请求

了解了同源与他相反的就是跨域,也就是上面说的协议。域名、端口只要有一个不满足那么他们就是跨域。

浏览器对跨域请求的拦截,我们是能够正常发起对服务器的请求的,服务器也能够感应到请求并将数据返回回来,但是就在临近城门的时候,在浏览器门口就被一个同源策略的门卫拦截住了,一生之敌。

那么既然如此如何来实现跨域的请求呢?有两个方式CORS和JSONP。

cors是w3c标准支持get和post

JSONP

原理:由于浏览器同源策略的限制,网页无法通过ajax请求非同源,但是script这个标签是不受限制的,所以可以通过src这个属性请求到非同源的script

实现::自己定义一个回调函数,然后通过另一个script标签的src属性来调用服务器和一些参数在这个参数里面callback=这个函数的名字就是你自己回调函数的名字然后后面跟上你自己的参数

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script> function fn(data) {
console.log('调用成功');
console.log(data);
} </script>
<script src="http://www.liulongbin.top:3006/api/jsonp?callback=fn&name=张三&age=29&sex=男"></script> </body>
</html>

JSONP的缺点就是他只支持get请求

2.

jQuery中的JSONP,具体的格式如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>点击查看jsonp</button>
<script src="../day01/lib/jquery.js"></script>
<script>
$('button').on('click', () => {
$.ajax({
url : 'http://www.liulongbin.top:3006/api/jsonp?name=张三&age=29&sex=男',
dataType : 'jsonp',
jsonpCallback : 'fn',
success : res => console.log(res)
})
})
</script>
</body>
</html>

在这里面datatype必须制定,然后url中没有了callback,因为他会自己随机生成一个callback,你也可以自己修改,jsonpCallback是修改回调函数名字的,jsonp是修改callback的。

在jq中jsonp的一个运行过程也要知道一下,他其实也是依靠script标签来实现的,在请求的时候他会动态生成一个script标签在header,然后请求完成又会移出这个标签。

3.

这些都学完了就可以看到一个案例,模仿淘宝的搜索关键字案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入页面的基本样式 -->
<link rel="stylesheet" href="./css/search.css" />
<!-- 导入 jQuery -->
<script src="./lib/jquery.js"></script>
<!-- 3.1插入template 准备用到模板引擎 -->
<script src="./lib/template-web.js"></script>
<!-- 3.2定义ui结构 -->
<script type="text/html" id="suggestList">
{{each result}}
<div class="suggest-item">{{$value[0]}}</div>
{{/each}}
</script>
<style>
.suggest-list {
display: none;
border: 1px solid #ccc;
}
.suggest-item {
padding-left: 5px;
line-height: 30px;
}
.suggest-item:hover {
cursor: pointer;
background-color: #eee;
}
</style>
</head>
<body>
<div class="container">
<!-- Logo -->
<img src="./images/taobao_logo.png" alt="" class="logo" /> <div class="box">
<!-- tab 栏 -->
<div class="tabs">
<div class="tab-active">宝贝</div>
<div>店铺</div>
</div>
<!-- 搜索区域(搜索框和搜索按钮) -->
<div class="search-box">
<input type="text" class="ipt" placeholder="请输入要搜索的内容" /><button class="btnSearch">
搜索
</button>
</div>
<!-- 3.在搜索框下面添加一个盒子拿来装关键字列表 -->
<div class="suggest-list"> </div>
</div>
</div>
<script src="./lib/jquery.js"></script>
<script src="./lib/index.js"></script>
</body>
</html>

通过jsonp和前面说到的模板引擎来实现

$(function() {
// 1.先获取输入框的文字
$('.ipt').on('keyup', function(e) {
let iptText = $(this).val().trim()
if (iptText == '') {
// 4.搜索关键词为空时需要隐藏搜索列表
return $('.suggest-list').empty().hide()
} else {
// 2.1调用获取关键字函数
getSearchList(iptText)
}
})
// 2.封装获取建议列表的函数
function getSearchList(text) {
$.ajax({
url : 'http://suggest.taobao.com/sug?q='+text+'',
dataType : 'jsonp',
success : res => {
getHtml(res)
}
})
}
// 3.3调用函数并渲染
function getHtml(res) {
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
} else {
let htmlStr = template('suggestList', res)
console.log(htmlStr);
$('.suggest-list').html(htmlStr).show()
}
}
})

4.

防抖

防抖策略就是当一个事件被触发后,延迟几秒在执行回调函数,如果在这几秒内又被触发了,那么就会重新计时

主要应用场景在用户输入时连续输入一串字符,可以通过防抖策略只有在输入完毕过后再去执行查询的请求这样可以有效减少请求次数。

具体怎么来实现需要一个定时器,然后定义防抖函数,这个函数里面开启定时器获取jsonp数据渲染html都在这里面调用,在用户键盘事件这里清除定时器,输入一个清除一个输入一个清除一个,所以只要输入的够快,就达不到进入执行这个定时器的门槛,当你停下输入正常执行代码,就会开始执行定时器,去调用去请求去渲染

$(function() {
// 防抖1 定义一个延时器
var timer = null
// 防抖2 定义防抖函数
function debounceSearch(text) {
timer = setTimeout(() => {
getSearchList(text)
}, 500);
}
// 1.先获取输入框的文字
$('.ipt').on('keyup', function(e) {
// 防抖3一进来先清除定时器,按一下清一下
clearTimeout(timer)
let iptText = $(this).val().trim()
if (iptText == '') {
// 4.搜索关键词为空时需要隐藏搜索列表
return $('.suggest-list').empty().hide()
} else {
// 2.1调用获取关键字函数
// getSearchList(iptText)
// 防抖4 调用获取关键字函数由定时器执行相当于等你输完了在执行
debounceSearch(iptText)
}
})
// 2.封装获取建议列表的函数
function getSearchList(text) {
$.ajax({
url : 'http://suggest.taobao.com/sug?q='+text+'',
dataType : 'jsonp',
success : res => {
getHtml(res)
}
})
}
// 3.3调用函数并渲染
function getHtml(res) {
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
} else {
let htmlStr = template('suggestList', res)
console.log(htmlStr);
$('.suggest-list').html(htmlStr).show()
}
}
})

缓存搜索

就是当我们输入一个数据的时候又添加一个关键字,然后删了有输入第一个关键字这个时候请求了三次,其中第一次和第三次是重复的,怎么解决

先定义一个全局的缓存对象,将搜索结果缓存到缓存对象中,优先从缓存中获取数据.

$(function() {
// 防抖1 定义一个延时器
var timer = null
// 防抖2 定义防抖函数
function debounceSearch(text) {
timer = setTimeout(() => {
getSearchList(text)
}, 500);
}
// 缓存1 定义一个全局空对象
var resObj = {}
// 1.先获取输入框的文字
$('.ipt').on('keyup', function(e) {
// 防抖3一进来先清除定时器,按一下清一下
clearTimeout(timer)
let iptText = $(this).val().trim()
if (iptText == '') {
// 4.搜索关键词为空时需要隐藏搜索列表
return $('.suggest-list').empty().hide()
} else {
// 缓存3 当我们输入值得时候就去判断一下有没有对象里有没有该值如果有那直接渲染就是不用再去请求数据
if (resObj[iptText]) {
getHtml(resObj[iptText])
} else {
// 2.1调用获取关键字函数
// getSearchList(iptText)
// 防抖4 调用获取关键字函数由定时器执行相当于等你输完了在执行
debounceSearch(iptText)
} }
})
// 2.封装获取建议列表的函数
function getSearchList(text) {
$.ajax({
url : 'http://suggest.taobao.com/sug?q='+text+'',
dataType : 'jsonp',
success : res => {
console.log(res);
getHtml(res)
}
})
}
// 3.3调用函数并渲染
function getHtml(res) {
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
} else {
let htmlStr = template('suggestList', res)
// console.log(htmlStr);
$('.suggest-list').html(htmlStr).show()
// 缓存2 一切获取数据输入完毕在这里获取输入的最终值保存进对象里
resObj[$('.ipt').val().trim()] = res
}
}
})

5.

节流

节流策略就是可以减少一段时间事件的触发频率,通过一个节流阀达到本不需要这么高的触发率,让资源空出来

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body {
margin: 0;
padding: 0;
}
img {
position: absolute;
}
</style>
</head>
<body>
<img src="./angel.gif" alt=""> <script>
/* 普通版
var img = document.querySelector('img')
document.onmousemove = function(e) {
// console.log(11);
img.style.left = e.pageX + 'px'
img.style.top = e.pageY + 'px'
} */
// 节流版
var img = document.querySelector('img')
var timer = null
document.onmousemove = function(e) {
// console.log(11);
if (timer) {
return
} else {
timer = setTimeout(function() {
img.style.left = e.pageX + 'px'
img.style.top = e.pageY + 'px'
timer = null
},16)
}
console.log(11);
}
</script>
</body>
</html>

ajax - 终结篇jsonp,防抖节流的更多相关文章

  1. ajax终结篇

    Ajax中post和get的区别 在ajax中有这个方法 xmlreq.open("post","servlet/MyServlet?time="+newDat ...

  2. JS组件系列——表格组件神器:bootstrap table(三:终结篇,最后的干货福利)

    前言:前面介绍了两篇关于bootstrap table的基础用法,这章我们继续来看看它比较常用的一些功能,来个终结篇吧,毛爷爷告诉我们做事要有始有终~~bootstrap table这东西要想所有功能 ...

  3. 在没有DOM操作的日子里,我是怎么熬过来的(终结篇)

    前言 在我写终结篇的日子里,Vue版本稳定在2.9.1.当我摸清Vue的脉络之后,以一个爬坑无数的亲历者的身份,谈谈我在MVVM时代里遇到的那些事儿. 接下来,正文从这开始~ 好多童鞋学习Vue都有灯 ...

  4. jquery ajax中使用jsonp的限制(转)

    http://www.cnblogs.com/dudu/archive/2012/12/04/jquery_ajax_jsonp.html jsonp 解决的是跨域 ajax 调用的问题.为什么要跨域 ...

  5. 【跟着大佬学JavaScript】之lodash防抖节流合并

    前言 前面已经对防抖和节流有了介绍,这篇主要看lodash是如何将防抖和节流合并成一个函数的. 初衷是深入lodash,学习它内部的好代码并应用,同时也加深节流防抖的理解.这里会先从防抖开始一步步往后 ...

  6. 看看C# 6.0中那些语法糖都干了些什么(终结篇)

    终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...

  7. 一起学微软Power BI系列-官方文档-入门指南(7)发布与共享-终结篇+完整PDF文档

    接触Power BI的时间也只有几个月,虽然花的时间不多,但通过各种渠道了解收集,谈不上精通,但对一些重要概念和细节还是有所了解.在整理官方文档的过程中,也熟悉和了解了很多概念.所以从前到后把微软官方 ...

  8. JavaScript中的正则表达式(终结篇)

    JavaScript中的正则表达式(终结篇) 在之前的几篇文章中,我们了解了正则表达式的基本语法,但那些语法不是针对于某一个特定语言的.这篇博文我们将通过下面几个部分来了解正则表达式在JavaScri ...

  9. WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

随机推荐

  1. 嵌入式linux驱动开发 笔记

    @ 目录 首个驱动hellodrv 1.编写源码 2.编译模块 3.加载驱动 首个驱动hellodrv 3.如果下载不到,就自己编写,并编译驱动. 1.编写源码 2.编译模块 1.先写makefile ...

  2. location 匹配规则

    location 匹配规则 语法规则 location [=||*|^~] /uri/ { - } 模式 含义 location = /uri = 表示精确匹配,只有完全匹配上才能生效 locatio ...

  3. 架构师成长之路也该了解的新一代微服务技术-ServiceMesh(上)

    架构演进 发展历程 我们再来回顾一下架构发展历程,从前往后的顺序依次为单机小型机->垂直拆分->集群化负载均衡->服务化改造架构->服务治理->微服务时代 单机小型机:采 ...

  4. ubuntu16.04启动ssh服务

    1 查看ssh服务是否开启 ps -e | grep ssh* 2如果没有则安装ssh apt-get install openssh-server openssh-client 3再看服务就有ssh ...

  5. Spring Boot 的核心配置文件有哪几个?它们的区别是什么?

    Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件.application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置.b ...

  6. 使用 rabbitmq 的场景?

    1.服务间异步通信 2.顺序消费 3.定时任务 4.请求削峰

  7. Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?

    可以继承其他类或实现其他接口,在 Swing 编程和 Android 开发中常用此方式来 实现事件监听和回调.

  8. MariaDB ZIP方式安装(Window系统)

    Maria DB ZIP方式安装 Windows上ZIP包的入门非常简单-此发行版包括预构建的数据库文件,这些文件可以在解压缩ZIP后立即使用. 您可以从命令提示符运行mysqld.exe,如下所示: ...

  9. dp求最长递增子序列并输出

    1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.List; 4 5 /** 6 * Create ...

  10. Redis 集群的主从复制模型是怎样的?

    为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所 以集群使用了主从复制模型,每个节点都会有 N-1 个复制品.