iframe隐藏帧技术
- 在早期没有ajax的时候,前端程序员使用一种变通的技术来实现更新局部页面内容
- 这种技术依赖的就是
iframe标签
,它相当于是当前页面的子页面,使用target属性指向它的id后,后台返回数据就会返回到iframe标签中 - 将iframe标签隐藏起来,js操作它的父页面(使用parent获取到父页面,也就是当前页面),就是可以实现后端动态返回数据后,页面局部更新的功能
- 只做了解,现在几乎不用了
AJAX开发
AJAX操作流程
1.创建XMLHttpRequest
对象
2.对象调用open
方法传入参数,准备发送请求
3.对象调用send
方法发送请求
4.声明指定回调函数对象.onreadystatechange = function(){};
下面会具体介绍每步流程
创建xhr对象
-
var xhr = new XMLHttpRequest();
这样就可以创建好xhr对象 - 但是实际上
XMLHttpRequest()
这个构造函数存在一定的兼容问题,ie6及其以下版本是不支持这个对象的 - 一般IE6使用
var xhr = new ActiveXObject('Microsoft.HTTPXML')
来代替
准备发送
-
xhr.open('请求方式','目标url','异步或者同步标识')
使用xhr对象调用open方法,就能进入准备发送阶段,下面是对参数的接受 - 请求方式
- 一般前端最常用的请求方式就是get和post
- 建议是将请求发送的参数部分用变量存储起来再操作
- 如果使用
get
,那么发送的参数必须写在目标url后面,以?
问号来连接。多个参数以&
符号连接,并且为了防止中文出现乱码,还要将参数部分使用js内置的方法encodeURI()
来进行转码 - 如果使用
post
,那么参数部分是写在发送阶段的send()
方法中,参数不需要转码。另外使用post必须要在发送前设置请求头,xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
这个是固定格式,不需要了解直接用即可
- 如果使用
- 目标url就是你向发送数据到后端文件的url地址
- 异步或者同步标识是以true和false来代替,默认是true异步形式。基本不会用到同步的方式
执行发送
-
xhr.send();
这样就能发送请求了 - 关于要点,上面也提过了。如果是
get
方式参数写null
,如果是post
方式那么参数就写url的参数
指定回调函数
-
xhr.onreadystatechange() = function(){};
注意这个回调函数我们只是声明,是由浏览器来调用。调用的条件就是readyState
属性值发生变化(值为0,1的时候不调用),下面会详细介绍 - 回调函数中会涉及到的属性值:
-
xhr.readyState
这个属性一共由四个值:- 0标识xhr对象初始化成功
- 1表示xhr已经调用send()方法发送请求
- 2表示服务器端返回了数据,但未解析
- 3表示正在解析返回的数据
- 4表示解析成功,可以使用服务器端返回的数据
- 所以一般会在回调函数中判断该属性是否为4,为4再执行下一步操作
-
xhr.status
这是属性就是服务器端返回的状态码,常用的有:- 200服务器端成功返回数据
- 404请求的资源未找到
- 500服务器端错误
- 这个状态码实际上就是http请求的状态码
- 这个属性一般会在判断
readyState
属性后作二次判断,就是说哪怕readyState=4
,也只能说明成功解析了返回的数据,但不一定是正确。如果status值为200
才表示服务器端返回了正确的数据
-
服务器端响应的数据格式
-
xhr.responseXML
接收xml格式的响应数据,如果想要后端页面返回xml格式数据还要加上请求头header('Content-type:text/xml')
。但是这种数据格式现在基本不用了,因为它以标签对(元数据)的形式来描述数据内容,所以标签就占用了大量空间,并且也不利于解析,只做了解 -
xhr.responseText
接受字符串格式的响应数据,其中json数据字符串是现在最流行的数据格式,它的格式与js普通对象非常相似 - ajax目前就只支持这两种格式的响应数据
json数据介绍
- 数据格式
- 上面说过了,json数据与js普通对象格式几乎一致,只说一下它们的区别:
- json数据在返回的时候不需要变量来存放引用地址
- json数据的键必须用双引号来包裹
- json数据结束不需要分号
- 注意:json数据就是单纯的字符串,不是对象,需要转换
- 上面说过了,json数据与js普通对象格式几乎一致,只说一下它们的区别:
- 数据解析
- 原生JS内置了一个方法
JSON.parse(json数据)
,可以把接受到的json数据转换为对象,在通过对象访问属性的方式,就能获取到内部的数据 - 题外话:使用内置方法
JSON.stringify(对象)
,可以将对象转换成字符串,只做了解
- 原生JS内置了一个方法
- 后端API返回json数据
- 一般来说,后端都是从数据库中获取到数据,然后将数据存放在一个多维数组中,然后调用内置方法将数组转换成json格式数据(例如:PHP使用
json_encode(数组)
来转换),返回给前端
- 一般来说,后端都是从数据库中获取到数据,然后将数据存放在一个多维数组中,然后调用内置方法将数组转换成json格式数据(例如:PHP使用
同步和异步
- 原理分析
- 同步请求的方式浏览器会一直等待请求数据的返回,而不执行其他操作,这样就会造成一直在加载中不渲染的情况,可能会形成阻塞
- 而异步的请求的方式,浏览器会把请求交给xhr对象来处理,发送请求后浏览器不会一直等待继续在执行下面的代码,当请求到的数据返回后,浏览器执行数据操作,相当于是多条线在执行,所以也叫做多线程处理方式。异步经典的用法就是局部更新页面数据,不会让整个页面重新加载
- 举个例子:如果领导想让某个人来汇报工作,那么它会让秘书通知那个人到办公室。在秘书通知的过程中,领导并不会什么都不做只等人,而是依然做自己其他的事。当人来了之后再开始工作汇报,这个例子就和异步的原理一样
- 异步的底层原理理解
- 这里涉及到了js底层代码执行顺序,单线程+事件队列。单线程就是指从上往下依次执行代码,如果只有单线程执行方式,那么遇到有部分代码需要执行时间必须回造成阻塞,所以js就添加了事件队列机制
- 什么是事件队列呢?其实很简单,js执行到定时器、事件、ajax指定函数时,它会把回调函数放入事件队列中,然后继续执行下面的代码,并调用事件队列循环判断。当主线程处于空闲状态时,队列中的回调函数又满足条件就执行
- 所以事件队列中回调函数要执行必须满足如下条件:
- 如果该回调函数是定时器中的,那么首先要主线程空闲,然后定时器的时间条件满足才会执行
- 如果该回调函数是事件中的,那么首先要主线程空闲,然后事件触发才执行
- 如果该回调函数是ajax请求中的,那么首先要主线程空闲,然后服务器端响应了数据才执行
- 这样就很容易理解异步原理了,js将代码执行分成了两条线,主线程一直执行代码不会等待回调函数触发,当主线程处于空闲而回调函数又满足触发条件就把回调函数放入主线程立即执行,这中间没有什么都不干的等待过程,所以避免阻塞的情况出现
- 理解透彻这个原理
jq封装的ajax方法
- jquery中已经封装好了ajax方法,直接
$.ajax();
调用即可 - 介绍一下常用的属性,注意参数是以对象键值对的方式:
-
type
属性设置请求方式 -
url
属性设置发送地址 -
data
设置参数,参数部分也是对象键值对的方法 -
dataType
属性设置接收数据的格式 -
success
回调函数,接收到数据解析完成并正常时调用 -
error
回调函数,服务器端发生错误时调用
-
- 更多属性翻手册看
- 模拟jq封装的ajax方法原理,要搞清楚