服务器:上网过程中,负责存放和对外提供资源的电脑
客户端:上网过程中,负责获取和消费资源的电脑
URL地址:统一资源定位符,用于标识互联网上每个资源的唯一存放位置。浏览器只有通过URL地址,才能正确定位资源的存放位置,从而成功访问到对应的资源
URL地址一般由三部组成:
① 客户端与服务器之间的通信协议
② 存有该资源的服务器名称
③ 资源在服务器上具体的存放位置
网页请求数据:如果要在网页中请求服务器上的数据资源,则需要用到 XMLHttpRequest 对象用法 var xhrObj = new XMLHttpRequest()
资源的请求方式:为 get 和 post 请求
Ajax:在网页中利用 XMLHttpRequest 对象和服务器进行数据交互的方式,Ajax能让我们轻松实现网页与服务器之间的数据交互
jQuery 中发起 Ajax 请求最常用的三个方法:
$.get(),$.post() ,$.ajax()
$.get(url, [data], [callback])
//发起不带参数的请求
$.get('http://www.liulongbin.top:3006/api/getbooks', function(res) {
console.log(res) // 这里的 res 是服务器返回的数据
})
//发起带参数的请求
$.get('http://www.liulongbin.top:3006/api/getbooks', { id: 1 }, function(res) {
console.log(res)
})
//向服务器提交数据
$.post(url, [data], [callback])
$.ajax({
type: '', // 请求的方式,例如 GET 或 POST
url: '', // 请求的 URL 地址
data: { },// 这次请求要携带的数据
success: function(res) { } // 请求成功之后的回调函数
})
使用 Ajax 请求数据时,被请求的 URL 地址,就叫做数据接口(简称接口)。同时,每个接口必须有请求方式
接口测试工具Postman:为了验证接口能否被正常被访问,我们常常需要使用接口测试工具,来对数据接口进行检测。接口测试工具能让我们在不写任何代码的情况下,对接口进行调用和测试。
接口文档组成部分:包含以下6项内容,从而为接口的调用提供依据:
表单在网页中主要负责数据采集功能
表单由三个基本部分组成:
action:用来规定当提交表单时,向何处发送表单数据。
action 属性的值应该是后端提供的一个 URL 地址,这个 URL 地址专门负责接收表单提交过来的数据。
target:用来规定在何处打开 action URL
可选值有5个,默认情况下,target 的值是 _self,表示在相同的框架中打开 action URL
method:用来规定以何种方式把表单数据提交到 action URL
可选值有两个,分别是 get 和 post。
默认情况下,method 的值为 get,表示通过URL地址的形式,把表单数据提交到 action URL
get 方式适合用来提交少量的、简单的数据。
post 方式适合用来提交大量的、复杂的、或包含文件上传的数据。
在实际开发中,post 提交方式用的最多
注意:
定义:通过点击 submit 按钮,触发表单提交的操作,从而使页面跳转到 action URL 的行为,叫做表单的同步提交
缺点:
解决方案:表单只负责采集数据,Ajax 负责将数据提交到服务器
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" />
<input type="password" name="password" />
<button type="submit">提交button>
form>
<script>
$(function () {
// 第一种方式
// $('#f1').submit(function () {
// alert('监听到了表单的提交事件')
// })
// 第二种方式
$('#f1').on('submit', function () {
alert('监听到了表单的提交事件2')
})
})
script>
body>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" />
<input type="password" name="password" />
<button type="submit">提交button>
form>
<script>
$(function () {
// 第一种方式
// $('#f1').submit(function (e) {
// alert('监听到了表单的提交事件')
// e.preventDefault()
// })
// 第二种方式
$('#f1').on('submit', function (e) {
alert('监听到了表单的提交事件2')
e.preventDefault()
})
})
script>
body>
$(selector).serialize()
,可以一次性获取到表单中的所有的数据<body>
<form action="/login" id="f1">
<input type="text" name="user_name" />
<input type="password" name="password" />
<button type="submit">提交button>
form>
<script>
$(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>
可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面
优点:
简约、超快的模板引擎。
中文官网首页为 http://aui.github.io/art-template/zh-cn/index.html
下载链接:http://aui.github.io/art-template/zh-cn/docs/installation.html
传统UI结构渲染问题:结构复杂,修改麻烦
art-template 提供了 {{ }} 这种语法格式,在 {{ }} 内可以进行变量输出,或循环数组等操作,这种 {{ }} 语法在 art-template 中被称为标准语法。
在 {{ }} 语法中,可以进行变量的输出、对象属性的输出、三元表达式输出、逻辑或输出、加减乘除等表达式输出。
原文输出:
{{@ value }}
如果要输出的 value 值中,包含了 HTML 标签结构,则需要使用原文输出语法,才能保证 HTML 标签被正常渲染
条件输出:
则可以在 {{ }} 中使用if … else if … /if
的方式,进行按需输出
<div>
{{if flag === 0}}
flag的值是0
{{else if flag === 1}}
flag的值是1
{{/if}}
div>
循环输出:
如果要实现循环输出,则可以在 {{ }} 内,通过 each 语法循环数组,当前循环的索引使用 $index 进行访问,当前的循环项使用 $value 进行访问
<div>
{{each arr}}
{{$index}} {{$value}}
{{/each}}
div>
<ul>
{{each hobby}}
<li>索引是:{{$index}},循环项是:{{$value}}li>
{{/each}}
ul>
过滤器的本质,就是一个 function 处理函数
{{value | filterName}}
过滤器语法类似管道操作符,它的上一个输出作为下一个输入。
定义过滤器的基本语法:template.defaults.imports.filterName = function(value){/*return处理的结果*/}
<body>
<script type="text/html" id="tpl-user">
<h3>{{regTime | dateFormat}}</h3>
script>
<script>
// 定义处理时间的过滤器
template.defaults.imports.dateFormat = function (date) {
var y = date.getFullYear()
var m = date.getMonth() + 1
var d = date.getDate()
return y + '-' + m + '-' + d
}
script>
body>
正则与字符串操作
exec() 函数用于检索字符串中的正则表达式的匹配
如果字符串中有匹配的值,则返回该匹配值,否则返回 null
RegExpObject.exec(string)
var str = 'hello'
var pattern = /o/
// 输出的结果["o", index: 4, input: "hello", groups: undefined]
console.log(pattern.exec(str))
分组:
正则表达式中 ( ) 包起来的内容表示一个分组,可以通过分组来提取自己想要的内容
replace函数
用于在字符串中用一些字符替换另一些字符
var result = '123456'.replace('123', 'abc') // 得到的 result 的值为字符串 'abc456'
实现简易的模板引擎
实现步骤:
<script type="text/html" id="tpl-user">
<div>姓名:{{name}}</div>
<div>年龄:{{ age }}</div>
<div>性别:{{ gender}}</div>
<div>住址:{{address }}</div>
script>
<script>
// 定义数据
var data = { name: 'zs', age: 28, gender: '男', address: '北京顺义马坡' }
// 调用模板函数
var htmlStr = template('tpl-user', data)
// 渲染HTML结构
document.getElementById('user-box').innerHTML = htmlStr
script>
function template(id, data) {
var str = document.getElementById(id).innerHTML
var pattern = /{{\s*([a-zA-Z]+)\s*}}/
var pattResult = null
while ((pattResult = pattern.exec(str))) {
str = str.replace(pattResult[0], data[pattResult[1]])
}
return str
}
<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>
XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数据资源。之前所学的 jQuery 中的 Ajax 函数,就是基于 xhr 对象封装出来的
// 1. 创建 XHR 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数,指定 请求方式 与 URL地址
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
// 3. 调用 send 函数,发起 Ajax 请求
xhr.send()
// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
// 4.1 监听 xhr 对象的请求状态 readyState ;与服务器响应的状态 status
if (xhr.readyState === 4 && xhr.status === 200) {
// 4.2 打印服务器响应回来的数据
console.log(xhr.responseText)
}
}
XMLHttpRequest 对象的 readyState 属性,用来表示当前 Ajax 请求所处的状态。
使用 xhr 对象发起带参数的 GET 请求时,只需在调用 xhr.open 期间,为 URL 地址指定参数即可
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1')
查询字符串(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=西游记
对中文字符进行编码,用英文字符表示非英文字符
浏览器提供了 URL 编码与解码的 API,分别是:
encodeURI()
编码的函数
decodeURI()
解码的函数
// 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. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式。前端领域,经常提及的两种数据交换格式分别是 XML 和 JSON
XML 和 HTML 虽然都是标记语言,但是,它们两者之间没有任何的关系。
缺点:XML 格式臃肿,和数据无关的代码多,体积大,传输效率低
JSON 就是 Javascript 对象和数组的字符串表示法,它使用文本表示一个 JS 对象或数组的信息,因此,JSON 的本质是字符串
JSON 是一种轻量级的文本数据交换格式,比 XML 更小、更快、更易解析
JSON 中包含对象和数组两种结构,通过这两种结构的相互嵌套,可以表示各种复杂的数据结构
JSON的两种结构
对象结构和数组结构
对象结构:对象结构在JSON中表示为{}括起来的内容
key 必须是使用英文的双引号包裹的字符串,value 的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型
数据结构:{key:value, kay:value, …}的键值对结构
数据结构为 [ “java”, “javascript”, 30, true … ] 。数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型
JSON语法注意事项:
JSON和JS对象的关系:
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串
JSON和JS对象互转:
// 从 JSON 字符串转换为 JS 对象,使用 JSON.parse() 方法
var obj = JSON.parse('{"a": "Hello", "b": "World"}')
//结果是 {a: 'Hello', b: 'World'}
// 从 JS 对象转换为 JSON 字符串,使用 JSON.stringify() 方法
var json = JSON.stringify({a: 'Hello', b: 'World'})
//结果是 '{"a": "Hello", "b": "World"}'
序列化和反序列化:
把数据对象转换为字符串的过程,叫做序列化,例如:调用 JSON.stringify() 函数的操作,叫做 JSON 序列化。
把字符串转换为数据对象的过程,叫做反序列化,例如:调用 JSON.parse() 函数的操作,叫做 JSON 反序列化。
<script src="./itheima.js">script>
<script>
// 2. 调用自定义的 itheima 函数,发起 Ajax 数据请求
itheima({
method: '请求类型',
url: '请求地址',
data: { /* 请求参数对象 */ },
success: function(res) { // 成功的回调函数
console.log(res) // 打印数据
}
})
script>
定义options参数选项:
itheima()
函数是我们自定义的 Ajax 函数,它接收一个配置对象作为参数,配置对象中可以配置如下属性:
method
请求的类型url
请求的 URL 地址data
请求携带的数据success
请求成功之后的回调函数处理data参数
/**
* 处理 data 参数
* @param {data} 需要发送到服务器的数据
* @returns {string} 返回拼接好的查询字符串 name=zs&age=10
*/
function resolveData(data) {
var arr = []
for (var k in data) {
arr.push(k + '=' + data[k])
}
return arr.join('&')
}
定义itheima函数
在 itheima() 函数中,需要创建 xhr 对象,并监听 onreadystatechange 事件
function itheima(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)
}
}
}
判断请求的类型
不同的请求类型,对应 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)
}
旧版缺点:无法读取和上传文件
;没有进度信息
新功能:可以设置 HTTP 请求的时限
,可以使用 FormData 对象管理表单数据
,可以上传文件
,可以获得数据传输的进度信息
设置HTTP请求时限:timeout 属性
xhr.timeout = 3000
xhr.ontimeout = function(event){
alert('请求超时!')
}
FormData对象管理表单数据
Ajax 操作往往用来提交表单数据。为了方便表单处理,HTML5 新增了一个 FormData 对象,可以模拟表单操作
// 1. 创建 FormData 实例
var fd = new FormData()
// 2. 调用 append 函数,向 fd 中追加数据
fd.append('uname', 'zs')
fd.append('upwd', '123456')
var xhr = new XMLHttpRequest()
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))
}
}
FormData对象也可以用来获取网页表单的值
// 获取表单元素
var form = document.querySelector('#form1')
// 监听表单元素的 submit 事件
form.addEventListener('submit', function(e) {
e.preventDefault()
// 根据 form 表单创建 FormData 对象,会自动将表单数据填充到 FormData 对象中
var fd = new FormData(form)
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
xhr.onreadystatechange = function() {}
})
上传文件:
实现步骤:
<input type="file" id="file1" />
<button id="btnUpload">上传文件button>
<br />
<img src="" alt="" id="img" width="800" />
// 1. 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload')
// 2. 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
// 3. 获取到选择的文件列表
var files = document.querySelector('#file1').files
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
// ...后续业务逻辑
})
// 1. 创建 FormData 对象
var fd = new FormData()
// 2. 向 FormData 中追加文件
fd.append('avatar', files[0])
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数,指定请求类型与URL地址。其中,请求类型必须为 POST
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
// 3. 发起请求
xhr.send(fd)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)
if (data.status === 200) { // 上传文件成功
// 将服务器返回的图片地址,设置为 标签的 src 属性
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else { // 上传文件失败
console.log(data.message)
}
}
}
显示文件上传进度:
<link rel="stylesheet" href="./lib/bootstrap.css" />
<script src="./lib/jquery.js">script>
<div class="progress" style="width: 500px; margin: 10px 0;">
<div class="progress-bar progress-bar-info progress-bar-striped active" id="percent" style="width: 0%">
0%
div>
div>
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
// 1. 计算出当前上传进度的百分比
var percentComplete = Math.ceil((e.loaded / e.total) * 100)
$('#percent')
// 2. 设置进度条的宽度
.attr('style', 'width:' + percentComplete + '%')
// 3. 显示当前的上传进度百分比
.html(percentComplete + '%')
}
}
xhr.upload.onload = function() {
$('#percent')
// 移除上传中的类样式
.removeClass()
// 添加上传完成的类样式
.addClass('progress-bar progress-bar-success')
}
<script src="./lib/jquery.js">script>
<input type="file" id="file1" />
<button id="btnUpload">上传button>
$('#btnUpload').on('click', function() {
// 1. 将 jQuery 对象转化为 DOM 对象,并获取选中的文件列表
var files = $('#file1')[0].files
// 2. 判断是否选择了文件
if (files.length <= 0) {
return alert('请选择图片后再上传!‘)
}
})
// 向 FormData 中追加文件
var fd = new FormData()
fd.append('avatar', files[0])
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
// 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值
contentType: false,
// 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器
processData: false,
success: function(res) {
console.log(res)
}
})
// 自 jQuery 版本 1.8 起,该方法只能被附加到文档
$(document).ajaxStart(function() {
$('#loading').show()
})
// 自 jQuery 版本 1.8 起,该方法只能被附加到文档
$(document).ajaxStop(function() {
$('#loading').hide()
})
Axios 是专注于网络数据请求的库。
相比于原生的 XMLHttpRequest 对象,axios 简单易用。
相比于 jQuery,axios 更加轻量化,只专注于网络数据请求
axios.get('url', { params: { /*参数*/ } }).then(callback)
// 请求的 URL 地址
var url = 'http://www.liulongbin.top:3006/api/get'
// 请求的参数对象
var paramsObj = { name: 'zs', age: 20 }
// 调用 axios.get() 发起 GET 请求
axios.get(url, { params: paramsObj }).then(function(res) {
// res.data 是服务器返回的数据
var result = res.data
console.log(res)
})
axios.post('url', { /*参数*/ }).then(callback)
// 请求的 URL 地址
var url = 'http://www.liulongbin.top:3006/api/post'
// 要提交到服务器的数据
var dataObj = { location: '北京', address: '顺义' }
// 调用 axios.post() 发起 POST 请求
axios.post(url, dataObj).then(function(res) {
// res.data 是服务器返回的数据
var result = res.data
console.log(result)
})
//语法
axios({
method: '请求类型',
url: '请求的URL地址',
data: { /* POST数据 */ },
params: { /* GET参数 */ }
}) .then(callback)
//直接使用axios发起GET请求
axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/get',
params: { // GET 参数要通过 params 属性提供
name: 'zs',
age: 20
}
}).then(function(res) {
console.log(res.data)
})
//直接使用axios发起POST请求
axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: { // POST 数据要通过 data 属性提供
bookname: '程序员的自我修养',
price: 666
}
}).then(function(res) {
console.log(res.data)
})
如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源
同源策略是浏览器提供的一个安全功能,A 网站的 JavaScript,不允许和非同源的网站 C 之间,进行资源的交互
MDN 官方给定的概念:同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
同源指的是两个 URL 的协议、域名、端口一致,反之,则是跨域
出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。
浏览器对跨域请求的拦截
浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!
如何实现跨域数据请求
实现跨域数据请求,最主要的两种解决方案,分别是 JSONP 和 CORS
JSONP:出现的早,兼容性好(兼容低版本IE)。是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案。缺点是只支持 GET 请求,不支持 POST 请求。
CORS:出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。支持 GET 和 POST 请求。缺点是不兼容某些低版本的浏览器
含义:是 JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题
实现原理:由于浏览器同源策略的限制,网页中无法通过 Ajax 请求非同源的接口数据。但是
因此,JSONP 的实现原理,就是通过
<script>
function success(data) {
console.log('获取到了data数据:')
console.log(data)
}
script>
<script src="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=success&name=zs&age=20">script>
由于 JSONP 是通过
注意:JSONP 和 Ajax 之间没有任何关系,不能把 JSONP 请求数据的方式叫做 Ajax,因为 JSONP 没有用到 XMLHttpRequest 这个对象
jQuery 提供的 $.ajax() 函数,除了可以发起真正的 Ajax 数据请求之外,还能够发起 JSONP 数据请求。默认情况下,使用 jQuery 发起 JSONP 请求,会自动携带一个 callback=jQueryxxx 的参数,jQueryxxx 是随机生成的一个回调函数名称
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',
// 如果要使用 $.ajax() 发起 JSONP 请求,必须指定 datatype 为 jsonp
dataType: 'jsonp',
success: function(res) {
console.log(res)
}
})
在使用 jQuery 发起 JSONP 请求时,如果想要自定义 JSONP 的参数以及回调函数名称,可以通过如下两个参数来指定
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',
dataType: 'jsonp',
// 发送到服务端的参数名称,默认值为 callback
jsonp: 'callback',
// 自定义的回调函数名称,默认值为 jQueryxxx 格式
jsonpCallback: 'abc',
success: function(res) {
console.log(res)
}
})
jQuery 中的 JSONP,也是通过
标签的 src 属性实现跨域数据访问的,只不过,jQuery 采用的是动态创建和移除标签的方式,来发起 JSONP 数据请求。
在发起 JSONP 请求的时候,动态向
中 append 一个
标签;
在 JSONP 请求成功以后,动态从
中移除刚才 append 进去的