ajax - 终结篇jsonp,防抖节流
今天是我们最后一天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,防抖节流的更多相关文章
- ajax终结篇
Ajax中post和get的区别 在ajax中有这个方法 xmlreq.open("post","servlet/MyServlet?time="+newDat ...
- JS组件系列——表格组件神器:bootstrap table(三:终结篇,最后的干货福利)
前言:前面介绍了两篇关于bootstrap table的基础用法,这章我们继续来看看它比较常用的一些功能,来个终结篇吧,毛爷爷告诉我们做事要有始有终~~bootstrap table这东西要想所有功能 ...
- 在没有DOM操作的日子里,我是怎么熬过来的(终结篇)
前言 在我写终结篇的日子里,Vue版本稳定在2.9.1.当我摸清Vue的脉络之后,以一个爬坑无数的亲历者的身份,谈谈我在MVVM时代里遇到的那些事儿. 接下来,正文从这开始~ 好多童鞋学习Vue都有灯 ...
- jquery ajax中使用jsonp的限制(转)
http://www.cnblogs.com/dudu/archive/2012/12/04/jquery_ajax_jsonp.html jsonp 解决的是跨域 ajax 调用的问题.为什么要跨域 ...
- 【跟着大佬学JavaScript】之lodash防抖节流合并
前言 前面已经对防抖和节流有了介绍,这篇主要看lodash是如何将防抖和节流合并成一个函数的. 初衷是深入lodash,学习它内部的好代码并应用,同时也加深节流防抖的理解.这里会先从防抖开始一步步往后 ...
- 看看C# 6.0中那些语法糖都干了些什么(终结篇)
终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...
- 一起学微软Power BI系列-官方文档-入门指南(7)发布与共享-终结篇+完整PDF文档
接触Power BI的时间也只有几个月,虽然花的时间不多,但通过各种渠道了解收集,谈不上精通,但对一些重要概念和细节还是有所了解.在整理官方文档的过程中,也熟悉和了解了很多概念.所以从前到后把微软官方 ...
- JavaScript中的正则表达式(终结篇)
JavaScript中的正则表达式(终结篇) 在之前的几篇文章中,我们了解了正则表达式的基本语法,但那些语法不是针对于某一个特定语言的.这篇博文我们将通过下面几个部分来了解正则表达式在JavaScri ...
- WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享
系列文章目录 WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...
随机推荐
- 数据库原理 之MySQL
数据库种类: 关系型数据库: mysql 专注于数据安全 和功能 ,存取时 会有表的结构化操作解析sql语句---- 丢给磁盘存取 ----取出,结构化成表 常用关系型数据库产品介绍oracle数据库 ...
- python prettytable 模块
#coding:utf-8 # qianxiao996精心制作 from prettytable import PrettyTable x = PrettyTable(["名称", ...
- Python 局域网主机存活扫描
#! python # -*- coding: utf-8 -*- __author__ = 'Deen' import os import threading import argparse # 从 ...
- python练习册 每天一个小程序 第0008题
1 # -*-coding:utf-8-*- 2 __author__ = 'Deen' 3 ''' 4 题目描述: 5 一个HTML文件,找出里面的正文. 6 7 思路: 8 利用Beautiful ...
- InnoDB什么时候会锁表?
我们常常说InnoDB是行锁,但是这里介绍一下它锁表的情况. InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的.InnoDB ...
- SpringAOP--aop使用
SpringAOP使用方式 切点表达式 常用的符号: *:匹配任何数量字符: ..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包:而在方法参数模式中匹配任何数量参数. +:匹配指定类型的子类 ...
- 请说出作用域public,private,protected,以及不写时的区别?
这四个作用域的可见范围如下表所示.说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly.作用域 当前类 同一package 子孙类 其他packagepublic ...
- 当一个线程进入某个对象的一个 synchronized 的实例方 法后,其它线程是否可进入此对象的其它方法?
如果其他方法没有 synchronized 的话,其他线程是可以进入的. 所以要开放一个线程安全的对象时,得保证每个方法都是线程安全的.
- 什么是 Spring 引导的执行器?
Spring Boot 执行程序提供了 restful Web 服务,以访问生产环境中运行应用程序 的当前状态.在执行器的帮助下,您可以检查各种指标并监控您的应用程序.
- NULL 是什么意思 ?
NULL 这个值表示 UNKNOWN(未知):它不表示""(空字符串).对 NULL 这 个值的任何比较都会生产一个 NULL 值.您不能把任何值与一个 NULL 值进行比 较,并 ...