目录

服务器基本概念

1.URL

2.URL地址的组成部分

3. 图解客户端与服务器的通信过程

4.网页中如何请求数据

5.资源的请求方式

Ajax

jQuery中的Ajax

1. $.get()函数的语法

2.$.post()函数的语法

3.$.ajax()函数的语法

接口

1.接口的请求过程

2..接口测试工具

3.接口文档

4.接口文档组成部分

form表单的基本使用(通过点击submit提交按钮同步提交数据)

1.表单的组成部分

2.

标签的属性(action,target,method,enctype)

3.表单的同步提交及缺点(通过点击submit提交按钮)

通过Ajax提交表单数据(jQuery)

1.监听表单提交事件

2.阻止表单默认提交行为

3.快速获取表单的数据(jQuery的serialize()函数)

4.案例(评论列表)

5.渲染UI结构时遇到的问题

模板引擎(art-template)

1.art-template模板引擎

2.使用传统方式渲染UI结构(不用模板引擎,用jQuery语法)

3.art-template模板引擎的基本使用

4.art-template标准语法(输出,原文输出,条件输出,循环输出,过滤器)

5.art-template模板引擎的基本使用(演示)

6.模板引擎的实现原理(正则表达式与字符串操作)

7.实现简易的模板引擎

原生Ajax

XMLHttpRequest的基本使用

1.使用xhr发起GET请求

2.xhr对象的readyState属性(值0到4)

3. 使用xhr发起带参数的GET请求(?拼接参数查询字符串)

4.查询字符串

5.GET请求携带参数的本质(将参数以查询字符串的形式,追加到 URL 地址的后面)

6.URL编码与解码(使用英文字符去表示非英文字符)

7.使用xhr发起POST请求

数据交换格式(XML 和 JSON)

1.XML

2.XML的缺点

3.JSON

4.JSON的两种结构(对象和数组)

5.JSON和JS对象的关系

6.序列化和反序列化(数据对象和字符串相互转化)

封装自己的Ajax函数(原生)

步骤1.仿jQuery的$Ajax()定义options参数选项

步骤2.处理data参数

步骤3.定义ajax函数

步骤4.判断请求类型

XMLHttpRequest Level2的新特性(HTTP 请求的时限、 FormData 对象管理表单数据、上传文件、数据传输的进度信息)

1. 旧版XMLHttpRequest的缺点

2.XMLHttpRequest Level2的新功能

3.设置HTTP请求时限(xhr的属性:xhr.timeout 和事件ontimeout)

4.FormData对象管理表单数据(提交表单数据,获取网页表单的值)

5.上传文件(onreadystatechange 事件)

6.显示文件上传进度(xhr.upload.onprogress 事件)

jQuery高级用法

jQuery实现文件上传

jQuery实现loading效果

axios(专注于网络数据请求的库)

1.axios发起GET请求

2.axios发起POST请求

3.直接使用axios发起请求(get或post)

同源策略和跨域策略

同源策略

跨域

1.浏览器对跨域请求的拦截

2. 如何实现跨域数据请求(JSONP,CORS)

JSONP(JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题)

JSONP的实现

1.原理

2.自己实现一个简单的JSONP

3.JSONP的缺点

4.jQuery中的JSONP

5.jQuery中JSONP的实现过程

淘宝搜索推荐案例

输入框的防抖

防抖和节流

节流

1.节流的应用场景

2.鼠标跟随效果案例

总结防抖和节流的区别

HTTP协议

HTTP协议简介

1.通信协议

2.HTTP协议

3.HTTP协议的交互模型

HTTP请求消息

1.HTTP请求消息的组成部分(请求行、请求头部 、空行 和 请求体)

HTTP响应消息

1.HTTP响应消息的组成部分

HTTP请求方法

HTTP响应状态代码

1.HTTP响应状态码的组成及分类

2. 2** 成功相关的响应状态码

3. 3** 重定向相关的响应状态码

4. 4** 客户端错误相关的响应状态码

5. 5** 服务端错误相关的响应状态码


服务器基本概念

1.URL

URL(全称是UniformResourceLocator)中文叫统一资源定位符,用于标识互联网上每个资源的唯一存放位置。浏览器只有通过URL地址,才能正确定位资源的存放位置,从而成功访问到对应的资源。

2.URL地址的组成部分

① 客户端与服务器之间的通信协议

② 存有该资源的服务器名称

③ 资源在服务器上具体的存放位置

3. 图解客户端与服务器的通信过程

 注意: (1)客户端与服务器之间的通信过程,分为 请求 – 处理 – 响应 三个步骤。

(2)网页中的每一个资源,都是通过 请求 – 处理 – 响应 的方式从服务器获取回来的。

4.网页中如何请求数据

 如果要在网页中请求服务器上的数据资源,则需要用到 XMLHttpRequest 对象。 XMLHttpRequest(简称 xhr)是浏览器提供的 js 成员,通过它,可以请求服务器上的数据资源。

最简单的用法 var xhrObj = new XMLHttpRequest()

5.资源的请求方式

客户端请求服务器时,请求的方式有很多种,最常见的两种请求方式分别为 get 和 post 请求。 (1) get 请求通常用于获取服务端资源(向服务器要资源)    

  例如:根据 URL 地址,从服务器获取 HTML 文件、css 文件、js文件、图片文件、数据资源等  (2)post 请求通常用于向服务器提交数据(往服务器发送资源)    

  例如:登录时向服务器提交的登录信息、注册时向服务器提交的注册信息、添加用户时向服务器提交的用户信息等各种数据提交操作

Ajax

Ajax 的全称是 Asynchronous Javascript And XML(异步 JavaScript 和 XML)。

通俗的理解:在网页中利用 XMLHttpRequest 对象和服务器进行数据交互的方式,就是Ajax。

Ajax能让我们轻松实现网页与服务器之间的数据交互。

Ajax的典型应用场景:

(1)用户名检测:注册用户时,通过 ajax 的形式,动态检测用户名是否被占用

(2)搜索提示:当输入搜索关键字时,通过 ajax 的形式,动态加载搜索提示列表

(3)数据分页显示:当点击页码值的时候,通过 ajax 的形式,根据页码值动态刷新表格的数据

(4)数据的增删改查:数据的添加、删除、修改、查询操作,都需要通过 ajax 的形式,来实现数据的交互。

jQuery中的Ajax

浏览器中提供的 XMLHttpRequest 用法比较复杂,所以 jQuery 对 XMLHttpRequest 进行了封装,提供了一系列 Ajax 相关的函数,极大地降低了 Ajax 的使用难度。 jQuery 中发起 Ajax 请求最常用的三个方法如下:

 $.get()

 $.post()

 $.ajax()

1. $.get()函数的语法

jQuery 中 $.get() 函数的功能单一,专门用来发起 get 请求,从而将服务器上的资源请求到客户端来进行使用。

$.get() 函数的语法如下:

$.get(url, [data], [callback])

其中,三个参数各自代表的含义如下:

<body><button id="btnGET">发起不带参数的GET请求</button><script>$(function () {$('#btnGET').on('click', function () {$.get('http://www.liulongbin.top:3006/api/getbooks', function (res) {console.log(res)})})})</script>
</body><body><button id="btnGETINFO">发起单参数的GET请求</button><script>$(function () {$('#btnGETINFO').on('click', function () {$.get('http://www.liulongbin.top:3006/api/getbooks', { id: 1 }, function (res) {console.log(res)})})})</script>
</body>

2.$.post()函数的语法

jQuery 中 $.post() 函数的功能单一,专门用来发起 post 请求,从而向服务器提交数据。

$.post() 函数的语法如下:

$.post(url, [data], [callback])

其中,三个参数各自代表的含义如下:

<body><button id="btnPOST">发起POST请求</button><script>$(function() {$('#btnPOST').on('click', function() {$.post('http://www.liulongbin.top:3006/api/addbook', {bookname: '水浒传',author: '施耐庵',publisher: '天津图书出版社'}, function(res) {console.log(res)})})})</script>
</body>

3.$.ajax()函数的语法

相比于 $.get() 和 $.post() 函数,jQuery 中提供的 $.ajax() 函数,是一个功能比较综合的函数,它允许我们对 Ajax 请求进行更详细的配置。

$.ajax() 函数的基本语法如下:

$.ajax({  

         type: '',         // 请求的方式,例如 GET 或 POST ,(type也可以写成method )

          url: '',          // 请求的 URL 地址    

        data: {   },        // 这次请求要携带的数据    

        success: function(res) { }         // 请求成功之后的回调函数

})

<body><button id="btnGET">发起GET请求</button><script>$(function() {$('#btnGET').on('click', function() {$.ajax({type: 'GET',url: 'http://www.liulongbin.top:3006/api/getbooks',data: {id: 1},success: function(res) {console.log(res)}})})})</script>
</body><body><button id="btnPOST">发起POST请求</button><script>$(function () {$('#btnPOST').on('click', function () {$.ajax({type: 'POST',url: 'http://www.liulongbin.top:3006/api/addbook',data: {bookname: '史记',author: '司马迁',publisher: '上海图书出版社'},success: function (res) {console.log(res)}})})})</script>
</body>

接口

使用 Ajax 请求数据时,被请求的 URL 地址,就叫做数据接口(简称接口)。

同时,每个接口必须有请求方式。

例如:

http://www.liulongbin.top:3006/api/getbooks   获取图书列表的接口(GET请求) http://www.liulongbin.top:3006/api/addbook    添加图书的接口(POST请求)

1.接口的请求过程

通过GET或POST方式请求接口的过程

2..接口测试工具

postman

aippost

3.接口文档

接口文档,顾名思义就是接口的说明文档,它是我们调用接口的依据。好的接口文档包含了对接口URL,参数以及输出内容的说明,我们参照接口文档就能方便的知道接口的作用,以及接口如何进行调用。

4.接口文档组成部分

接口文档可以包含很多信息,也可以按需进行精简,不过,一个合格的接口文档,应该包含以下6项内容,从而为接口的调用提供依据:

(1) 接口名称:用来标识各个接口的简单说明,如登录接口,获取图书列表接口等。

(2)接口URL:接口的调用地址。

(3)调用方式:接口的调用方式,如 GET 或 POST

(4)参数格式:接口需要传递的参数,每个参数必须包含参数名称、参数类型、是否必选、参数说明这4项内容。

(5) 响应格式:接口的返回值的详细描述,一般包含数据名称、数据类型、说明3项内容。

(6)返回示例(可选):通过对象的形式,例举服务器返回数据的结构。

form表单的基本使用(通过点击submit提交按钮同步提交数据)

表单在网页中主要负责数据采集功能。HTML中的<form>标签,就是用于采集用户输入的信息,并通过<form>标签的提交操作,把采集到的信息提交到服务器端进行处理。

<form><input type="text" name="email_or_mobile" /><input type="password" name="password" /><input type="checkbox" name="remember_me" checked /><button type="submit">提交</button>
</form>

1.表单的组成部分

表单由三个基本部分组成: 表单标签, 表单域, 表单按钮

2.<form>标签的属性(action,target,method,enctype)

<form>标签用来采集数据,<form>标签的属性则是用来规定如何把采集到的数据发送到服务器。

(1)  action

action 属性用来规定当提交表单时,向何处发送表单数据

action 属性的值应该是后端提供的一个 URL 地址,这个 URL 地址专门负责接收表单提交过来的数据。

当 <form> 表单在未指定 action 属性值的情况下,action 的默认值当前页面的 URL 地址

注意:当提交表单后,页面会立即跳转到 action 属性指定的 URL 地址

(2)target

target 属性用来规定在何处打开 action URL。

它的可选值有5个,默认情况下,target 的值是 _self,表示在相同的框架中打开 action URL。

 (3)method

method 属性用来规定以何种方式把表单数据提交到 action URL。

它的可选值有两个,分别是 get 和 post。

默认情况下,method 的值为 get,表示通过URL地址的形式,把表单数据提交到 action URL。

注意:

get 方式适合用来提交少量的、简单的数据。

post 方式适合用来提交大量的、复杂的、或包含文件上传的数据。

在实际开发中,<form> 表单的 post 提交方式用的最多,很少用 get。例如登录、注册、添加数据等表单操作,都需要使用 post 方式来提交表单。

(4)enctype

enctype 属性用来规定在发送表单数据之前如何对数据进行编码。

它的可选值有三个,默认情况下,enctype 的值为 application/x-www-form-urlencoded,表示在发送前编码所有的字符。

注意:

在涉及到文件上传的操作时,必须将 enctype 的值设置为 multipart/form-data

如果表单的提交不涉及到文件上传操作,则直接将 enctype 的值设置为 application/x-www-form-urlencoded或者不写该属性 即可!

    <form action="/login" target="_blank" method="post"><input type="text" name="email_or_mobile" /><input type="password" name="password" /><button type="submit">提交</button></form>

3.表单的同步提交及缺点(通过点击submit提交按钮)

通过点击 submit 按钮,触发表单提交的操作,从而使页面跳转到 action URL 的行为,叫做表单的同步提交。

缺点:

<form>表单同步提交后,整个页面会发生跳转,跳转到 action URL 所指向的地址,用户体验很差。

<form>表单同步提交后,页面之前的状态和数据会丢失。

解决方案:表单只负责采集数据,Ajax 负责将数据提交到服务器。

通过Ajax提交表单数据(jQuery)

1.监听表单提交事件

在 jQuery 中,可以使用如下两种方式,监听到表单的提交事件:

$('#form1').submit(function(e) {alert('监听到了表单的提交事件')
})$('#form1').on('submit', function(e) {alert('监听到了表单的提交事件')
})

2.阻止表单默认提交行为

当监听到表单的提交事件以后,可以调用事件对象的 event.preventDefault() 函数,来阻止表单的提交和页面的跳转,示例代码如下:

$('#form1').submit(function(e) {// 阻止表单的提交和页面的跳转e.preventDefault()
})$('#form1').on('submit', function(e) {// 阻止表单的提交和页面的跳转e.preventDefault()
})

3.快速获取表单的数据(jQuery的serialize()函数)

为了简化表单中数据的获取操作,jQuery 提供了 serialize() 函数,其语法格式如下:

$('#f1').serialize()

serialize()函数:可以一次性获取到表单的所有数据

注意:在使用 serialize() 函数快速获取表单数据时,必须为每个表单元素添加 name 属性!

<body><form action="/login" id="f1"><input type="text" name="user_name" /><input type="password" name="password" /><button type="submit">提交</button></form><script>// 注意:在使用 serialize() 函数快速获取表单数据时,// 必须为每个表单元素添加 name 属性!$(function() {// 第一种方式/* $('#f1').submit(function (e) {e.preventDefault()var data = $(this).serialize()console.log(data)}) */// 第二种方式$('#f1').on('submit', function(e) {e.preventDefault()var data = $('#f1').serialize()console.log(data)})})</script>
</body>

4.案例(评论列表)

<body style="padding: 15px;"><!-- 评论面板 --><div class="panel panel-primary"><div class="panel-heading"><h3 class="panel-title">发表评论</h3></div><form class="panel-body" id="formAddCmt"><div>评论人:</div><input type="text" class="form-control" name="username" autocomplete="off" /><div>评论内容:</div><textarea class="form-control" name="content"></textarea><button type="submit" class="btn btn-primary">发表评论</button></form></div><!-- 评论列表 --><ul class="list-group" id="cmt-list"><li class="list-group-item"><span class="badge" style="background-color: #F0AD4E;">评论时间:</span><span class="badge" style="background-color: #5BC0DE;">评论人:</span> Item 1</li></ul>

’js文件

//先定义一个获取评论列表的方法
function getCommentList() {// 先用Ajax请求服务器数据获取评论列表数据,查看api接口文档$.ajax({method: 'GET',url: 'http://www.liulongbin.top:3006/api/cmtlist',success: function(res) { //请求成功的回调函数if (res.status !== 200) return alert('获取评论列表失败!')var rows = []$.each(res.data, function(i, item) { //每获取一个data数据就循环一次函数,循环拼接字符串var str = '<li class="list-group-item"><span class="badge" style="background-color: #F0AD4E;">评论时间:' + item.time + '</span><span class="badge" style="background-color: #5BC0DE;">评论人:' + item.username + '</span>' + item.content + '</li>'rows.push(str)})// 获取评论列表ul,empty()清空里面的子节点,append()拼接新的数据的等,join(‘’)数组转成字符串$('#cmt-list').empty().append(rows.join('')) // 渲染列表的UI结构}})
}getCommentList() //调用方法,刷新页面列表评论$(function() {// 监听表单提交事件$('#formAddCmt').submit(function(e) {// 阻止表单默认提交行为e.preventDefault()// serialize快速的到表单的数据var data = $(this).serialize()// 发起post请求,将表单数据提交到服务器$.post('http://www.liulongbin.top:3006/api/addcmt', data, function(res) {if (res.status !== 201) {return alert('发表评论失败!')}// 刷新评论列表内容getCommentList()// 清空表单内容,中间的[0]是将其转为原生DOM,再使用原生DOM才有的reset()方法$('#formAddCmt')[0].reset()})})
})

5.渲染UI结构时遇到的问题

通过字符串拼接的形式,来渲染UI结构。 如果UI结构比较复杂,则拼接字符串的时候需要格外注意引号之前的嵌套。且一旦需求发生变化,修改起来也非常麻烦。

解决办法:模板引擎

模板引擎(art-template)

模板引擎,顾名思义,它可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面。

模板引擎的好处:

减少了字符串的拼接操作

使代码结构更清晰

使代码更易于阅读与维护

1.art-template模板引擎

art-template 是一个简约、超快的模板引擎。

中文官网首页为 http://aui.github.io/art-template/zh-cn/index.html

在浏览器中访问 http://aui.github.io/art-template/zh-cn/docs/installation.html 页面,找到下载链接后,鼠标右键,选择“链接另存为”,将 art-template 下载到本地,然后,通过 <script> 标签加载到网页上进行使用。

2.使用传统方式渲染UI结构(不用模板引擎,用jQuery语法)

<body><div id="title"></div><div>姓名:<span id="name"></span></div><div>年龄:<span id="age"></span></div><div>会员:<span id="isVIP"></span></div><div>注册时间:<span id="regTime"></span></div><div>爱好:<ul id="hobby"><li>爱好1</li><li>爱好2</li></ul></div><script>var data = {title: '<h3>用户信息</h3>',name: 'zs',age: 20,isVIP: true,regTime: new Date(),hobby: ['吃饭', '睡觉', '打豆豆']}$(function () {$('#name').html(data.name)$('#title').html(data.title)$('#age').html(data.age)$('#isVIP').html(data.isVIP)$('#regTime').html(data.regTime)var rows = []$.each(data.hobby, function (i, item) {rows.push('<li>' + item + '</li>')})$('#hobby').html(rows.join(''))})</script>

3.art-template模板引擎的基本使用

(1)导入 art-template(引入js文件<script src="./lib/template-web.js"></script>)

(2)定义数据 (在script标签内)

(3)定义模板(在另一个script标签内,但属性type一定要写type="text/html")

(4)调用 template ()函数(在script标签内)

(5)渲染HTML结构(调用完template函数赋给的变量用innerHTML)

4.art-template标准语法(输出,原文输出,条件输出,循环输出,过滤器)

art-template 提供了 {{ }} 这种语法格式,在 {{ }} 内可以进行变量输出,或循环数组等操作,这种 {{ }} 语法在 art-template 中被称为标准语法。

(1)输出

在 {{ }} 语法中,可以进行变量的输出、对象属性的输出、三元表达式输出、逻辑或输出、加减乘除等表达式输出。

{{value}}   //变量输出
{{obj.key}}   //对象属性输出
{{obj['key']}}   //对象属性输出
{{a ? b : c}}    //三元式输出
{{a || b}}        //逻辑或输出
{{a + b}}        //加减乘除

(2)原文输出

如果要输出的 value 值中,包含了 HTML 标签结构,则需要使用原文输出语法,才能保证 HTML 标签被正常渲染。

{{@ value }}

(3)条件输出

如果要实现条件输出,则可以在 {{ }} 中使用 if … else if … /if 的方式,进行按需输出。

{{if value}} 按需输出的内容 {{/if}}{{if 判断条件}} 按需输出的内容 {{else if 判断条件2}} 按需输出的内容 {{/if}}

(4)循环输出

如果要实现循环输出,则可以在 {{ }} 内,通过 each 语法循环数组,当前循环的索引使用 $index 进行访问,当前的循环项使用 $value 进行访问。

{{each arr}}{{$index}} {{$value}}
{{/each}}

(5)过滤器

过滤器的本质,就是一个 function 处理函数。(写在模板中)

{{value | filterName}}

过滤器语法类似管道操作符,它的上一个输出作为下一个输入。 定义过滤器(写在script标签中)的基本语法如下:

template.defaults.imports.filterName = function(value){/*return处理的结果*/}
       // 定义处理时间的过滤器template.defaults.imports.dateFormat = function(date) {var y = date.getFullYear()var m = date.getMonth() + 1var d = date.getDate()return y + '-' + m + '-' + d}

5.art-template模板引擎的基本使用(演示)

(1)导入 art-template

引入js文件 :  <script src="./lib/template-web.js"></script>

(2)定义数据

写在script标签内

(3)定义模板

在另一个script标签内,其中属性type一定要写type="text/html"

    <!--模板的 HTML 结构,必须定义到 script 中 属性一定写type="text/html"--><script type="text/html" id="tpl-user"><h1>{{name}} ------ {{age}}</h1>{{@ test}}<div>{{if flag === 0}} flag的值是0 {{else if flag === 1}} flag的值是1 {{/if}}</div><ul>{{each hobby}}<li>索引是:{{$index}},循环项是:{{$value}}</li>{{/each}}</ul><h3>{{regTime | dateFormat}}</h3></script>

(4)调用 template ()函数

写在script标签内,template('模板的id名',需要渲染的数据对象)

        // 4. 调用 template 函数var htmlStr = template('tpl-user', data)

(5)渲染HTML结构(调用完template函数赋给的变量用innerHTML)

    // 5. 渲染HTML结构var con = document.querySelector('#container');con.innerHTML = htmlStr;

全代码演示:

    <title>Document</title><!-- 1. 导入模板引擎 --><!-- 在 window 全局,多一个函数,叫做 template('模板的Id', 需要渲染的数据对象) --><script src="./lib/template-web.js"></script><script src="./lib/jquery.js"></script>
</head><body><div id="container"></div><!-- 3. 定义模板 --><!-- 3.1 模板的 HTML 结构,必须定义到 script 中 属性一定写type="text/html"--><script type="text/html" id="tpl-user"><!-- 输出 --><h1>{{name}} ------ {{age}}</h1><!-- 原文输出:如果要输出的 value 值中,包含了 HTML 标签结构,则需要使用原文输出语法,才能保证 HTML 标签被正常渲染。 -->{{@ test}}<div><!-- 条件输出 -->{{if flag === 0}} flag的值是0 {{else if flag === 1}} flag的值是1 {{/if}}</div><ul><!-- 循环输出 -->{{each hobby}}<li>索引是:{{$index}},循环项是:{{$value}}</li>{{/each}}</ul><!-- 过滤器 --><h3>{{regTime | dateFormat}}</h3></script><script>// 定义处理时间的过滤器template.defaults.imports.dateFormat = function(date) {var y = date.getFullYear()var m = date.getMonth() + 1var d = date.getDate()return y + '-' + m + '-' + d}// 2. 定义需要渲染的数据var data = {name: 'zs',age: 20,// test值包含了html标签必须用原文输出@test: '<h3>测试原文输出</h3>',flag: 1,hobby: ['吃饭', '睡觉', '写代码'],regTime: new Date()}// 4. 调用 template 函数var htmlStr = template('tpl-user', data)console.log(htmlStr)// 5. 渲染HTML结构var con = document.querySelector('#container').innerHTML = htmlStr;// $('#container').html(htmlStr)</script>
</body>

6.模板引擎的实现原理(正则表达式与字符串操作)

(1)exec() 函数

exec() 函数用于检索字符串中的正则表达式的匹配。

如果字符串中有匹配的值,则返回该匹配值,否则返回 null。

var str = 'hello'
var pattern = /o/
// 输出的结果["o", index: 4, input: "hello", groups: undefined]
console.log(pattern.exec(str))

(2)分组

正则表达式中 ( ) 包起来的内容表示一个分组,可以通过分组来提取自己想要的内容,提取出{{}}中的内容放到数组索引为1的地方,示例代码如下:

    <script>var str = '<div>我是{{name}}</div>'var pattern = /{{([a-zA-Z]+)}}/var result = pattern.exec(str)console.log(result)</script>

(3)字符串的replace函数

replace() 函数用于在字符串中用一些字符替换另一些字符,语法格式如下:

var result = '123456'.replace('123', 'abc')
// 得到的 result 的值为字符串 'abc456'

(4)多次replace

var str = '<div>{{name}}今年{{ age }}岁了</div>'
var pattern = /{{\s*([a-zA-Z]+)\s*}}/var patternResult = pattern.exec(str)
str = str.replace(patternResult[0], patternResult[1])
console.log(str) // 输出 <div>name今年{{ age }}岁了</div>patternResult = pattern.exec(str)
str = str.replace(patternResult[0], patternResult[1])
console.log(str) // 输出 <div>name今年age岁了</div>patternResult = pattern.exec(str)
console.log(patternResult) // 输出 null

(5)用while循环进行replace

var str = '<div>{{name}}今年{{ age }}岁了</div>'
var pattern = /{{\s*([a-zA-Z]+)\s*}}/var patternResult = null
while(patternResult = pattern.exec(str)) {str = str.replace(patternResult[0], patternResult[1])
}
console.log(str) // 输出 <div>name今年age岁了</div>

(6)replace替换为真值

var data = { name: '张三', age: 20 }
var str = '<div>{{name}}今年{{ age }}岁了</div>'
var pattern = /{{\s*([a-zA-Z]+)\s*}}/var patternResult = null
while ((patternResult = pattern.exec(str))) {str = str.replace(patternResult[0], data[patternResult[1]])
}
console.log(str)

7.实现简易的模板引擎

(1)定义模板结构

<!-- 定义模板结构 -->
<script type="text/html" id="tpl-user"><div>姓名:{{name}}</div><div>年龄:{{ age }}</div><div>性别:{{  gender}}</div><div>住址:{{address  }}</div>
</script>

(2)预调用模板引擎

<script>// 定义数据var data = { name: 'zs', age: 28, gender: '男', address: '北京顺义马坡' }// 调用模板函数var htmlStr = template('tpl-user', data)// 渲染HTML结构document.getElementById('user-box').innerHTML = htmlStr
</script>

(3)封装template函数

function template(id, data) {var str = document.getElementById(id).innerHTMLvar pattern = /{{\s*([a-zA-Z]+)\s*}}/var pattResult = nullwhile ((pattResult = pattern.exec(str))) {str = str.replace(pattResult[0], data[pattResult[1]])}return str
}

(4)导入并使用自定义的模板引擎

<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>自定义模板引擎</title><!-- 导入自定义的模板引擎 --><script src="./js/template.js"></script>
</head>

原生Ajax

XMLHttpRequest的基本使用

9XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数据资源。之前所学的 jQuery 中的 Ajax 函数,就是基于 xhr 对象封装出来的。

1.使用xhr发起GET请求

步骤:

(1)创建 xhr 对象

(2)调用 xhr.open() 函数

(3)调用 xhr.send() 函数

(4)监听 xhr.onreadystatechange 事件

    <script>// 1. 创建 XHR 对象var xhr = new XMLHttpRequest()// 2. 调用 open 函数xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')// 3. 调用 send 函数xhr.send()// 4. 监听 onreadystatechange 事件xhr.onreadystatechange = function() {// 监听 xhr 对象的请求状态 readyState ;与服务器响应的状态 statusif (xhr.readyState === 4 && xhr.status === 200) {// 获取服务器响应的数据console.log(xhr.responseText)}}</script>

2.xhr对象的readyState属性(值0到4)

XMLHttpRequest 对象的 readyState 属性,用来表示当前 Ajax 请求所处的状态。每个 Ajax 请求必然处于以下状态中的一个:

3. 使用xhr发起带参数的GET请求(?拼接参数查询字符串)

使用 xhr 对象发起带参数的 GET 请求时,只需在调用 xhr.open 期间,为 URL 地址指定参数即可:

    <script>var xhr = new XMLHttpRequest()// 这种在 URL 地址后面拼接的参数,叫做查询字符串,用问号拼接xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1')xhr.send()xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log(xhr.responseText)}}// 查询字符串:将英文的 ? 放在URL 的末尾,然后再加上 参数=值 ,// 想加上多个参数的话,使用 & 符号进行分隔。//以这个形式,可以将想要发送给服务器的数据添加到 URL 中。</script>

这种在 URL 地址后面用?拼接的参数,叫做查询字符串。

4.查询字符串

定义:查询字符串(URL 参数)是指在 URL 的末尾加上用于向服务器发送信息的字符串(变量)。 格式:将英文的 ? 放在URL 的末尾,然后再加上 参数=值 ,想加上多个参数的话,使用 & 符号进行分隔。以这个形式,可以将想要发送给服务器的数据添加到 URL 中。

// 不带参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks
// 带一个参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks?id=1
// 带两个参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记

5.GET请求携带参数的本质(将参数以查询字符串的形式,追加到 URL 地址的后面

无论使用 $.ajax(),还是使用 $.get(),又或者直接使用 xhr 对象发起 GET 请求,当需要携带参数的时候,本质上,都是直接将参数以查询字符串的形式,追加到 URL 地址的后面,发送到服务器的。

$.get('url', {name: 'zs', age: 20}, function() {})
// 等价于
$.get('url?name=zs&age=20', function() {})$.ajax({ method: 'GET', url: 'url',data: {name: 'zs', age: 20}, success: function() {} })
// 等价于
$.ajax({ method: 'GET', url: 'url?name=zs&age=20',success: function() {} })

6.URL编码与解码(使用英文字符去表示非英文字符)

URL 地址中,只允许出现英文相关的字母、标点符号、数字,因此,在 URL 地址中不允许出现中文字符。 如果 URL 中需要包含中文这样的字符,则必须对中文字符进行编码(转义)。 URL编码的原则:使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。 URL编码原则的通俗理解:使用英文字符去表示非英文字符。

http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记
// 经过 URL 编码之后,URL地址变成了如下格式:
http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=%E8%A5%BF%E6%B8%B8%E8%AE%B0

浏览器提供了 URL 编码与解码的 API,分别是:

encodeURI()  编码的函数

decodeURI()  解码的函数

    <script>var str = '西游记'// encodeURI()  编码的函数var str2 = encodeURI(str)console.log(str2)console.log('----------')// decodeURI()  解码的函数var str3 = decodeURI('%E8%A5%BF%E6%B8%B8%E8%AE%B0')console.log(str3)</script>

URL编码的注意事项:

由于浏览器会自动对 URL 地址进行编码操作,因此,大多数情况下,程序员不需要关心 URL 地址的编码与解码操作。

更多关于 URL 编码的知识,请参考如下博客: https://blog.csdn.net/Lxd_0111/article/details/78028889

7.使用xhr发起POST请求

步骤:

(1)创建 xhr 对象

(2)调用 xhr.open() 函数

(3)设置 Content-Type 属性(固定写法)

(4)调用 xhr.send() 函数,同时指定要发送的数据

(5)监听 xhr.onreadystatechange 事件

    <script>// 1. 创建 xhr 对象var xhr = new XMLHttpRequest()// 2. 调用 open 函数xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')// 3. 设置 Content-Type 属性,固定写法xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')// 4. 调用 send 函数xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社')// 5. 监听事件xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log(xhr.responseText)}}</script>

数据交换格式(XML 和 JSON)

数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式。

前端领域,经常提及的两种数据交换格式分别是 XML 和 JSON。其中 XML 用的非常少,重点学习的数据交换格式就是 JSON

1.XML

XML 的英文全称是 EXtensible Markup Language,即可扩展标记语言。因此,XML 和 HTML 类似,也是一种标记语言。

  XML和HTML的区别

XML 和 HTML 虽然都是标记语言,但是,它们两者之间没有任何的关系。

(1)HTML 被设计用来描述网页上的内容,是网页内容的载体

(2)XML 被设计用来传输和存储数据,是数据的载体

2.XML的缺点

(1)XML 格式臃肿,和数据无关的代码多,体积大,传输效率低

(2)在 Javascript 中解析 XML 比较麻烦

3.JSON

  • 概念:JSON 的英文全称是 JavaScript Object Notation,即“JavaScript 对象表示法”。简单来讲,JSON 就是 Javascript 对象和数组的字符串表示法,它使用文本表示一个 JS 对象或数组的信息,因此,JSON 的本质是字符串
  • 作用:JSON 是一种轻量级的文本数据交换格式,在作用上类似于 XML,专门用于存储和传输数据,但是 JSON 比 XML 更小、更快、更易解析
  • 现状:JSON 是在 2001 年开始被推广和使用的数据格式,到现今为止,JSON 已经成为了主流的数据交换格式。

4.JSON的两种结构(对象和数组)

JSON 就是用字符串来表示 Javascript 的对象和数组。所以,JSON 中包含对象和数组两种结构,通过这两种结构的相互嵌套,可以表示各种复杂的数据结构。

(1)对象结构:对象结构在 JSON 中表示为 { } 括起来的内容。数据结构为 { key: value, key: value, … } 的键值对结构。其中,key 必须是使用英文的双引号包裹的字符串,value 的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型。

(2) 数组结构:数组结构在 JSON 中表示为 [ ] 括起来的内容。数据结构为 [ "java", "javascript", 30, true … ] 。数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型。()

 (3)JSON语法注意事项

  • 属性名必须使用双引号包裹
  • 字符串类型的值必须使用双引号包裹
  • JSON 中不允许使用单引号表示字符串
  • JSON 中不能写注释
  • JSON 的最外层必须是对象或数组格式
  • 不能使用 undefined 或函数作为 JSON 的值

JSON 的作用:在计算机与网络之间存储和传输数据。

JSON 的本质:用字符串来表示 Javascript 对象数据或数组数据

5.JSON和JS对象的关系

JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。例如:

//这是一个对象
var obj = {a: 'Hello', b: 'World'}//这是一个 JSON 字符串,本质是一个字符串
var json = '{"a": "Hello", "b": "World"}'
  • 要实现从 JSON 字符串转换为 JS 对象,使用 JSON.parse() 方法
  • 要实现从 JS 对象转换为 JSON 字符串,使用 JSON.stringify() 方法
    <script>// 要实现从 JSON 字符串转换为 JS 对象,使用 JSON.parse() 方法:var jsonStr = '{"a": "Hello", "b": "world"}'var obj = JSON.parse(jsonStr)console.log(obj)// 要实现从 JS 对象转换为 JSON 字符串,使用 JSON.stringify() 方法:var obj2 = {a: 'hello',b: 'world',c: false}var str = JSON.stringify(obj2)console.log(str)console.log(typeof str)</script>

6.序列化和反序列化(数据对象和字符串相互转化

  • 把数据对象转换为字符串的过程,叫做序列化,例如:调用 JSON.stringify() 函数的操作,叫做 JSON 序列化。
  • 把字符串转换为数据对象的过程,叫做反序列化,例如:调用 JSON.parse() 函数的操作,叫做 JSON 反序列化。

封装自己的Ajax函数(原生)

// 需要把 data 对象,转化成查询字符串的格式,从而提交给服务器,因此提前定义 resolveData 函数
function resolveData(data) {var arr = []for (var k in data) {var str = k + '=' + data[k]arr.push(str)}// 返回拼接好的查询字符串 name=zs&age=10return arr.join('&')
}function ajax(options) {var xhr = new XMLHttpRequest()// 把外界传递过来的参数对象,转换为 查询字符串var qs = resolveData(options.data)// toUpperCase()转成大写if (options.method.toUpperCase() === 'GET') {// 发起GET请求xhr.open(options.method, options.url + '?' + qs)xhr.send()} else if (options.method.toUpperCase() === 'POST') {// 发起POST请求xhr.open(options.method, options.url)xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')xhr.send(qs)}xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {// 将json字符串转换为一个对象或数组var result = JSON.parse(xhr.responseText)options.success(result)}}
}

步骤1.仿jQuery的$Ajax()定义options参数选项

ajax()函数是我们自定义的 Ajax 函数,它接收一个配置对象作为参数,配置对象中可以配置如下属性:

  • method   请求的类型
  • url           请求的 URL 地址
  • data        请求携带的数据
  • success   请求成功之后的回调函数

步骤2.处理data参数

需要把 data 对象,转化成查询字符串的格式,从而提交给服务器,因此提前定义 resolveData 函数如下:


function resolveData(data) {var arr = []for (var k in data) {arr.push(k + '=' + data[k])}return arr.join('&')
}

步骤3.定义ajax函数

需要创建 xhr 对象,并监听 onreadystatechange 事件:

function ajax(options) {var xhr = new XMLHttpRequest()// 拼接查询字符串var qs = resolveData(options.data)// 监听请求状态改变的事件xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {var result = JSON.parse(xhr.responseText)options.success(result)}}
}

步骤4.判断请求类型

不同的请求类型,对应 xhr 对象的不同操作,因此需要对请求类型进行 if … else … 的判断:

  if (options.method.toUpperCase() === 'GET') {// 发起 GET 请求xhr.open(options.method, options.url + '?' + qs)xhr.send()} else if (options.method.toUpperCase() === 'POST') {// 发起 POST 请求xhr.open(options.method, options.url)xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')xhr.send(qs)}

XMLHttpRequest Level2的新特性(HTTP 请求的时限、 FormData 对象管理表单数据、上传文件、数据传输的进度信息)

1. 旧版XMLHttpRequest的缺点

  • 只支持文本数据的传输,无法用来读取和上传文件
  • 传送和接收数据时,没有进度信息,只能提示有没有完成

2.XMLHttpRequest Level2的新功能

  • 可以设置 HTTP 请求的时限
  • 可以使用 FormData 对象管理表单数据
  • 可以上传文件
  • 可以获得数据传输的进度信息

3.设置HTTP请求时限(xhr的属性:xhr.timeout 和事件ontimeout)

有时,Ajax 操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。新版本的 XMLHttpRequest 对象,增加了 timeout 属性,可以设置 HTTP 请求的时限:

 xhr.timeout = 3000

上面的语句,将最长等待时间设为 3000 毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个 timeout 事件,用来指定回调函数:

 xhr.ontimeout = function(event){alert('请求超时!')}

<body><script>var xhr = new XMLHttpRequest()// 设置 超时时间 单位是毫秒xhr.timeout = 30// 设置超时以后的处理函数xhr.ontimeout = function() {console.log('请求超时了!')}xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')xhr.send()xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log(xhr.responseText)}}</script>
</body>

4.FormData对象管理表单数据(提交表单数据,获取网页表单的值)

(1)Ajax 操作往往用来提交表单数据。为了方便表单处理,HTML5 新增了一个 FormData 对象,可以模拟表单操作

      // 1. 新建 FormData 对象var fd = new FormData()// 2. 为 FormData 添加表单项fd.append('uname', 'zs')fd.append('upwd', '123456')// 3. 创建 XHR 对象var xhr = new XMLHttpRequest()// 4. 指定请求类型与URL地址xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')// 5. 直接提交 FormData 对象,这与提交网页表单的效果,完全一样xhr.send(fd)xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log(JSON.parse(xhr.responseText))}}

(2)FormData对象也可以用来获取网页表单的值

<body><form id="form1"><!-- autocomplete='off'阻止自动填充行为 --><input type="text" name="uname" autocomplete="off" /><input type="password" name="upwd" /><button type="submit">提交</button></form><script>// 1. 通过 DOM 操作,获取到 form 表单元素var form = document.querySelector('#form1')form.addEventListener('submit', function(e) {// 阻止表单的默认提交行为e.preventDefault()// 根据 form 表单创建 FormData 对象,会自动将表单数据填充到 FormData 对象中var fd = new FormData(form)var xhr = new XMLHttpRequest()// 开始发起post请求xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')xhr.send(fd)xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log(JSON.parse(xhr.responseText))}}})</script>

5.上传文件(onreadystatechange 事件

新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。

实现步骤:

  • 定义 UI 结构
  • 验证是否选择了文件
  • 向 FormData 中追加文件
  • 使用 xhr 发起上传文件的请求
  • 监听 onreadystatechange 事件

<body><!-- 1. 文件选择框 --><input type="file" id="file1" /><!-- 2. 上传文件的按钮 --><button id="btnUpload">上传文件</button><br /><!-- 3. img 标签,来显示上传成功以后的图片 --><img src="" alt="" id="img" width="800" /><script>// 1. 获取到文件上传按钮var btnUpload = document.querySelector('#btnUpload')// 2. 为按钮绑定单击事件处理函数btnUpload.addEventListener('click', function() {// 3. 获取到用户选择的文件列表,这个files是个数组var files = document.querySelector('#file1').filesif (files.length <= 0) {return alert('请选择要上传的文件!')}var fd = new FormData()// 将用户选择的文件,添加到 FormData 中fd.append('avatar', files[0])var xhr = new XMLHttpRequest()xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')xhr.send(fd)xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {var data = JSON.parse(xhr.responseText)if (data.status === 200) {// 上传成功,将服务器返回的图片地址,设置为 <img> 标签的 src 属性document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url} else {// 上传失败console.log('图片上传失败!' + data.message)}}}})</script>
</body>

6.显示文件上传进度(xhr.upload.onprogress 事件)

新版本的 XMLHttpRequest 对象中,可以通过监听 xhr.upload.onprogress 事件,来获取到文件的上传进度。语法格式如下:

 // 创建 XHR 对象var xhr = new XMLHttpRequest()// 监听 xhr.upload 的 onprogress 事件xhr.upload.onprogress = function(e) {// e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度if (e.lengthComputable) {// e.loaded 已传输的字节// e.total  需传输的总字节var percentComplete = Math.ceil((e.loaded / e.total) * 100)}}
    <title>Document</title><link rel="stylesheet" href="./lib/bootstrap.css" /><script src="./lib/jquery.js"></script>
</head><body><!-- 1. 文件选择框 --><input type="file" id="file1" /><!-- 2. 上传文件的按钮 --><button id="btnUpload">上传文件</button><!-- bootstrap 中的进度条 --><div class="progress" style="width: 500px; margin: 15px 10px;"><div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">0%</div></div><br /><!-- 3. img 标签,来显示上传成功以后的图片 --><img src="" alt="" id="img" width="800" /><script>// 1. 获取到文件上传按钮var btnUpload = document.querySelector('#btnUpload')// 2. 为按钮绑定单击事件处理函数btnUpload.addEventListener('click', function() {// 3. 获取到用户选择的文件列表var files = document.querySelector('#file1').filesif (files.length <= 0) {return alert('请选择要上传的文件!')}var fd = new FormData()// 将用户选择的文件,添加到 FormData 中fd.append('avatar', files[0])var xhr = new XMLHttpRequest()// 监听文件上传的进度// 监听 xhr.upload 的 onprogress 事件xhr.upload.onprogress = function(e) {// e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度if (e.lengthComputable) {// 计算出上传的进度// e.loaded 已传输的字节// e.total  需传输的总字节var procentComplete = Math.ceil((e.loaded / e.total) * 100)console.log(procentComplete)// 动态设置进度条$('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')}}// 监听上传完成的事件xhr.upload.onload = function() {$('#percent').removeClass().addClass('progress-bar progress-bar-success')}xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')xhr.send(fd)xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {var data = JSON.parse(xhr.responseText)if (data.status === 200) {// 上传成功document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url} else {// 上传失败console.log('图片上传失败!' + data.message)}}}})</script>
</body>

jQuery高级用法

jQuery实现文件上传

1. 定义UI结构

2. 验证是否选择了文件

3. 向FormData中追加文件

4. 使用jQuery发起上传文件的请求

jQuery实现loading效果

1. ajaxStart(callback)

Ajax 请求开始时,执行 ajaxStart 函数。可以在 ajaxStart 的 callback 中显示 loading 效果,示例代码如下:

   // 自 jQuery 版本 1.8 起,该方法只能被附加到文档$(document).ajaxStart(function() {$('#loading').show()})

注意: $(document).ajaxStart() 函数会监听当前文档内所有的 Ajax 请求。

2. ajaxStop(callback)

Ajax 请求结束时,执行 ajaxStop 函数。可以在 ajaxStop 的 callback 中隐藏 loading 效果,示例代码如下:

 // 自 jQuery 版本 1.8 起,该方法只能被附加到文档$(document).ajaxStop(function() {$('#loading').hide()})

axios(专注于网络数据请求的库)

Axios 是专注于网络数据请求的库。

相比于原生的 XMLHttpRequest 对象,axios 简单易用。

相比于 jQuery,axios 更加轻量化,只专注于网络数据请求。

1.axios发起GET请求

 axios.get('url', { params: { /*参数*/ } }).then(callback)
        // 1.axios发起GET请求document.querySelector('#btn1').addEventListener('click', function() {var url = 'http://www.liulongbin.top:3006/api/get'var paramsObj = {name: 'zs',age: 20}//语法:axios.get('url', { params: { /*参数*/ } }).then(callback)axios.get(url, {params: paramsObj}).then(function(res) {// res.data 是服务器返回的数据console.log(res.data)})})

2.axios发起POST请求

axios.post('url', { /*参数*/ }).then(callback)
        //2.axios发起POST请求document.querySelector('#btn2').addEventListener('click', function() {// 请求的 URL 地址var url = 'http://www.liulongbin.top:3006/api/post'// 要提交到服务器的数据var dataObj = {address: '北京',location: '顺义区'}// 语法:axios.post('url', { /*参数*/ }).then(callback)axios.post(url, dataObj).then(function(res) {console.log(res.data)})})

3.直接使用axios发起请求(get或post)

axios 也提供了类似于 jQuery 中 $.ajax() 的函数,语法如下:

 axios({method: '请求类型',url: '请求的URL地址',data: { /* POST数据 */ },params: { /* GET参数 */ }}) .then(callback)
        //3.直接使用axios发起请求,get参数用params;post参数用data// get请求document.querySelector('#btn3').addEventListener('click', function() {var url = 'http://www.liulongbin.top:3006/api/get'var paramsData = {name: '钢铁侠',age: 35}axios({method: 'GET',url: url,params: paramsData}).then(function(res) {console.log(res.data)})})// post请求document.querySelector('#btn4').addEventListener('click', function() {axios({method: 'POST',url: 'http://www.liulongbin.top:3006/api/post',data: {name: '娃哈哈',age: 18,gender: '女'}}).then(function(res) {console.log(res.data)})})

同源策略和跨域策略

同源策略

如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源。

例如,下表给出了相对于 http://www.test.com/index.html 页面的同源检测:

同源策略(英文全称 Same origin policy)是浏览器提供的一个安全功能。

MDN 官方给定的概念:同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

通俗的理解:浏览器规定,A 网站的 JavaScript,不允许和非同源的网站 C 之间,进行资源的交互,例如:

  • 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
  • 无法接触非同源网页的 DOM
  • 无法向非同源地址发送 Ajax 请求

跨域

同源指的是两个 URL 的协议、域名、端口一致,反之,则是跨域。

出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。

网页:http://www.test.com/index.html

接口:http://www.api.com/userlist

1.浏览器对跨域请求的拦截

2. 如何实现跨域数据请求(JSONP,CORS)

现如今,实现跨域数据请求,最主要的两种解决方案,分别是 JSONP 和 CORS。

JSONP:出现的早,兼容性好(兼容低版本IE)。是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案。缺点是只支持 GET 请求,不支持 POST 请求

CORS:出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。支持 GET 和 POST 请求。缺点是不兼容某些低版本的浏览器。

JSONP(JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题)

JSONP (JSON with Padding) 是 JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。

JSONP的实现

1.原理

由于浏览器同源策略的限制,网页中无法通过 Ajax 请求非同源的接口数据。但是 <script> 标签不受浏览器同源策略的影响,可以通过 src 属性,请求非同源的 js 脚本

因此,JSONP 的实现原理,就是通过 <script> 标签的 src 属性请求跨域的数据接口,并通过函数调用的形式,接收跨域接口响应回来的数据。

2.自己实现一个简单的JSONP

定义一个 success 回调函数:

    <script>function abc(data) {console.log('拿到了Data数据:')console.log(data)}</script>

通过 <script> 标签,请求接口数据:

    <script src="http://ajax.frontend.bai.net:3006/api/jsonp?callback=abc"></script>

getdata.js文件:

abc({ name: 'ls', age: 30 })

3.JSONP的缺点

由于 JSONP 是通过 <script> 标签的 src 属性,来实现跨域数据获取的,所以,JSONP 只支持 GET 数据请求,不支持 POST 请求。

注意:JSONP 和 Ajax 之间没有任何关系,不能把 JSONP 请求数据的方式叫做 Ajax,因为 JSONP 没有用到 XMLHttpRequest 这个对象

4.jQuery中的JSONP

jQuery 提供的 $.ajax() 函数,除了可以发起真正的 Ajax 数据请求之外,还能够发起 JSONP 数据请求,例如:

 $.ajax({url: 'http://ajax.frontend.net:3006/api/jsonp?name=zs&age=20',// 如果要使用 $.ajax() 发起 JSONP 请求,必须指定 datatype 为 jsonpdataType: 'jsonp',success: function(res) {console.log(res)}})

默认情况下,使用 jQuery 发起 JSONP 请求,会自动携带一个 callback=jQueryxxx 的参数,jQueryxxx 是随机生成的一个回调函数名称。

自定义参数及回调函数名称

在使用 jQuery 发起 JSONP 请求时,如果想要自定义 JSONP 的参数以及回调函数名称,可以通过如下两个参数来指定:

 $.ajax({url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',dataType: 'jsonp',// 发送到服务端的参数名称,默认值为 callbackjsonp: 'callback',// 自定义的回调函数名称,默认值为 jQueryxxx 格式jsonpCallback: 'abc',success: function(res) {console.log(res)}})

5.jQuery中JSONP的实现过程

jQuery 中的 JSONP,也是通过 <script> 标签的 src 属性实现跨域数据访问的,只不过,jQuery 采用的是动态创建和移除 <script> 标签的方式,来发起 JSONP 数据请求。

  • 在发起 JSONP 请求的时候,动态向 <header> 中 append 一个 <script> 标签;
  • 在 JSONP 请求成功以后,动态从 <header> 中移除刚才 append 进去的 <script> 标签;

淘宝搜索推荐案例

    <!-- 导入页面的基本样式 --><link rel="stylesheet" href="./css/search.css" /><!-- 导入 jQuery --><script src="./lib/jquery.js"></script><!-- 导入模板引擎 --><script src="./lib/template-web.js"></script>
</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 id="ipt" type="text" class="ipt" placeholder="请输入要搜索的内容" /><button class="btnSearch">搜索</button></div><!-- 搜索建议列表 --><div id="suggest-list"></div></div></div><!-- 模板结构 --><script type="text/html" id="tpl-suggestList">{{each result}}<!--搜索建议项--><div class="suggest-item">{{$value[0]}}</div>{{/each}}</script><script>$(function() {// 1. 定义延时器的Idvar timer = null// 定义全局缓存对象var cacheObj = {}// 2. 定义防抖的函数function debounceSearch(kw) {timer = setTimeout(function() {getSuggestList(kw)}, 300)}// 为输入框绑定 keyup 事件$('#ipt').on('keyup', function() {// 3. 清空 timerclearTimeout(timer)var keywords = $(this).val().trim()if (keywords.length <= 0) {return $('#suggest-list').empty().hide()}// 先判断缓存中是否有数据if (cacheObj[keywords]) {return renderSuggestList(cacheObj[keywords])}// TODO:获取搜索建议列表// console.log(keywords)// getSuggestList(keywords)debounceSearch(keywords)})function getSuggestList(kw) {$.ajax({// q为关键词,kw是用户输入的文字url: 'https://suggest.taobao.com/sug?q=' + kw,dataType: 'jsonp',success: function(res) {// console.log(res)renderSuggestList(res)}})}// 渲染UI结构function renderSuggestList(res) {if (res.result.length <= 0) {return $('#suggest-list').empty().hide()}var htmlStr = template('tpl-suggestList', res)$('#suggest-list').html(htmlStr).show()// 1. 获取到用户输入的内容,当做键var k = $('#ipt').val().trim()// 2. 需要将数据作为值,进行缓存cacheObj[k] = res}})</script>
</body>

输入框的防抖

防抖策略(debounce)是当事件被触发后,延迟 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。

用户在输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减少请求次数,节约请求资源;

防抖和节流

节流

节流策略(throttle),顾名思义,可以减少一段时间内事件的触发频率。

1.节流的应用场景

  1. 鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
  2. 加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源;

2.鼠标跟随效果案例

    <style>html,body {margin: 0;padding: 0;overflow: hidden;}#angel {position: absolute;}</style>
</head><body><img src="./angel.gif" alt="" id="angel" /><script>$(function() {// 1. 获取到图片var angel = $('#angel')// 步骤1. 定义节流阀var timer = null// 2. 绑定 mousemove 事件$(document).on('mousemove', function(e) {// 步骤3:判断节流阀是否为空if (timer) {return}// 3. 设置图片的位置// 步骤2:开启延时器timer = setTimeout(function() {$(angel).css('top', e.pageY + 'px').css('left', e.pageX + 'px')console.log('ok')timer = null}, 16)})})</script>
</body>

总结防抖和节流的区别

  • 防抖:如果事件被频繁触发,防抖能保证只有最有一次触发生效!前面 N 多次的触发都会被忽略!
  • 节流:如果事件被频繁触发,节流能够减少事件触发的频率,因此,节流是有选择性地执行一部分事件!

HTTP协议

HTTP协议简介

1.通信协议

通信协议(Communication Protocol)是指通信的双方完成通信所必须遵守的规则和约定。

通俗的理解:通信双方采用约定好的格式来发送和接收消息,这种事先约定好的通信格式,就叫做通信协议。

客户端与服务器之间要实现网页内容的传输,则通信的双方必须遵守网页内容的传输协议。

网页内容又叫做超文本,因此网页内容的传输协议又叫做超文本传输协议(HyperText Transfer Protocol) ,简称 HTTP 协议。

2.HTTP协议

HTTP 协议即超文本传送协议 (HyperText Transfer Protocol) ,它规定了客户端与服务器之间进行网页内容传输时,所必须遵守的传输格式。

例如:

  •  客户端要以HTTP协议要求的格式把数据提交到服务器
  •  服务器要以HTTP协议要求的格式把内容响应给客户端

3.HTTP协议的交互模型

HTTP 协议采用了 请求/响应 的交互模型。

HTTP请求消息

由于 HTTP 协议属于客户端浏览器和服务器之间的通信协议。因此,客户端发起的请求叫做 HTTP 请求客户端发送到服务器的消息,叫做 HTTP 请求消息

注意:HTTP 请求消息又叫做 HTTP 请求报文。

1.HTTP请求消息的组成部分(请求行、请求头部 、空行 和 请求体)

HTTP 请求消息由请求行(request line)、请求头部( header ) 、空行 和 请求体 4 个部分组成。

(1)请求行

请求行由请求方式、URL 和 HTTP 协议版本 3 个部分组成,他们之间使用空格隔开。

(2)请求头部 – 常见的请求头字段

 (3)空行

最后一个请求头字段的后面是一个空行,通知服务器请求头部至此结束。

请求消息中的空行,用来分隔请求头部与请求体。

(4)请求体

请求体中存放的,是要通过 POST 方式提交到服务器的数据。

注意:只有 POST 请求才有请求体,GET 请求没有请求体!

HTTP响应消息

响应消息就是服务器响应给客户端的消息内容,也叫作响应报文。

1.HTTP响应消息的组成部分

HTTP响应消息由状态行、响应头部、空行 和 响应体 4 个部分组成,如下图所示:

(1)状态行

状态行由 HTTP 协议版本、状态码和状态码的描述文本 3 个部分组成,他们之间使用空格隔开;

 (2)响应头部

响应头部用来描述服务器的基本信息。响应头部由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔。

  (3)空行

在最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端响应头部至此结束。 响应消息中的空行,用来分隔响应头部与响应体。

(4)响应体

响应体中存放的,是服务器响应给客户端的资源内容。

HTTP请求方法

HTTP 请求方法,属于 HTTP 协议中的一部分,请求方法的作用是:用来表明要对服务器上的资源执行的操作。最常用的请求方法是 GET 和 POST。

HTTP响应状态代码

HTTP 响应状态码(HTTP Status Code),也属于 HTTP 协议的一部分,用来标识响应的状态。 响应状态码会随着响应消息一起被发送至客户端浏览器,浏览器根据服务器返回的响应状态码,就能知道这次 HTTP 请求的结果是成功还是失败了。

1.HTTP响应状态码的组成及分类

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字用来对状态码进行细分。 HTTP 状态码共分为 5 种类型:

完整的 HTTP 响应状态码,可以参考 MDN 官方文档 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

2. 2** 成功相关的响应状态码

2** 范围的状态码,表示服务器已成功接收到请求并进行处理。常见的 2** 类型的状态码如下:

3. 3** 重定向相关的响应状态码

3** 范围的状态码,表示表示服务器要求客户端重定向,需要客户端进一步的操作以完成资源的请求。常见的 3** 类型的状态码如下:

4. 4** 客户端错误相关的响应状态码

4** 范围的状态码,表示客户端的请求有非法内容,从而导致这次请求失败。常见的 4** 类型的状态码如下:

5. 5** 服务端错误相关的响应状态码

5** 范围的状态码,表示服务器未能正常处理客户端的请求而出现意外错误。常见的 5** 类型的状态码如下:

Ajax(jQuery封装),表单form提交(Ajax),art-template模板引擎,原生Ajax,XML和JSON,axios,跨域和JSONP,防抖和节流,HTTP协议相关推荐

  1. js实现表单form提交前进行确认提示

    在jquery中,可以使用confirm来弹出提示框,实现确认提交.下面小编举例讲解js实现表单form提交前进行确认提示. 工具/原料 js+html 代码编辑器:zend studio 10.0 ...

  2. 表单form提交前弹出确认对话框

    表单form提交前进弹出确认对话框 定义一个函数: <script language="javascript"> function sumbit_sure(){ var ...

  3. 表单Form提交数据和PHP数据处理

    一.先来认识一下表单有那些常用元素和属性: 1.<from 表单的属性有: name="表单名称" ,非必须但是为避免混乱,不同表单尽量用不同的名字,且应该与表单的功能相符: ...

  4. jquery表单form提交阻止页面全部刷新

    首先明确一点:form表单下,如果是针对form元素进行提交,整个页面都会刷新. 所以出现的问题是:当用户往输入框内输入内容分后,按回车或者点击提交按钮,往当前页面输出内容的局部刷新会被之后的整个页面 ...

  5. 实现表单form提交前进行确认提示 表单提交 确认对话框

    没想到有这么多人浏览这个文章,看来网络的文章害人不浅啊,我重新把代码格式化了,大家好好看吧. 感谢网友提醒,把οnsubmit="return sumbit_sure()" 改过来 ...

  6. jQuery中ajax用form表单方式提交数据

    给表单加ID值,如图: 写ajax方法,如图: servlet返回是否添加成功,如图: jsp页面 <div class="modal-content"><div ...

  7. 使用ajax方法实现form表单的提交

    2019独角兽企业重金招聘Python工程师标准>>> 在使用form表单的时候,一旦点击提交触发submit事件,一般会使得页面跳转,页面间的跳转等行为的控制权往往在后端,后端会控 ...

  8. 前后端交互之使用ajax方法实现form表单的提交

    转载于:使用ajax方法实现form表单的提交 - 程序员十三 - 博客园 (cnblogs.com)  οnsubmit="reutrn false":表示禁止表单提交. dat ...

  9. 使用ajax方法实现form表单的提交(Ajax和from提交的区别)

    写在前面的话 在使用form表单的时候,一旦点击提交触发submit事件,一般会使得页面跳转,页面间的跳转等行为的控制权往往在后端,后端会控制页面的跳转及数据传递,但是在某些时候不希望页面跳转,或者说 ...

最新文章

  1. css加载会造成阻塞吗
  2. DCS系统接地应用讨论
  3. Mac的访达中,如何只搜索当前文件夹的内容?
  4. python推荐系统-python 简易推荐系统实现
  5. 【JS】Vue.js实现简单的ToDoList(一)——前期准备
  6. matlab矩阵除以一个数字,matlab矩阵中每一行数除以一个数 | 学步园
  7. C#9就这么来了,.NET开发者该做点什么?
  8. CF1000G. Two-Paths(树形dp)
  9. python面向对象的概念_Python面向对象概念和三要素
  10. The7主题-汉化绿色版/免key导入demo/安装插件[更至v9.10.1]
  11. 创建可用实验快照(二)
  12. python字符串长度排序_python-对混合类型和不同长度的字符串进行排序
  13. python 包的使用 (二)——pyecharts
  14. 如何用drawInRect()显示中文?
  15. 大数乘法(C语言、数组模拟)
  16. 【预测模型】基于matlab GUI AR模型线性预测【含Matlab源码 942期】
  17. 微型计算机原理与接口技术朱金钧课后答案,微型计算机原理及应用技术 第3版...
  18. 远程桌面同步本地计算机,微软更新远程桌面应用现在终于可以在本地和远程计算机上复制文件...
  19. goland本地包import飘红
  20. 使用EPW计算孤立ME方程

热门文章

  1. POJ - 1077 Eight(A∗算法)
  2. Lytro 光场相机重对焦C++实现以及CUDA实现
  3. 项目开发经验谈之:设计失败的挫败感
  4. Ubuntu使用笔记——Synaptic
  5. 论文阅读:FlowNet 2.0: Evolution of Optical Flow Estimation with Deep Networks
  6. 谷歌出品,数据集搜索引擎上线了!
  7. 七层登录之新小知识点
  8. oracle voting disk 大小,2.Oracle Voting Disk 管理
  9. 重新连接网络后怎么设置计算机,路由器恢复出厂设置后怎么重新设置?
  10. iOS和tvOS游戏按需加载资源简介