js__Ajax__实践
2017-05-09 本文已影响31人
好奇而已
1: ajax 是什么?有什么作用?
-
Ajax是Asynchronous JavaScript and XML的缩写,这一技术能够向服务器请求额外的数据而无需卸载整个页面.
-
AJAX 在
浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求)从服务器获取数据
,这里的异步是指脱离当前浏览器页面的请求、加载等单独执行,这意味着可以在不重新加载整个网页的情况下,通过JavaScript接受服务器传来的数据,然后操作DOM将新数据对网页的某部分进行更新, -
Ajax是一种浏览器和服务器的
通讯技术
,Ajax不是浏览器自带功能 -
open()方法的第三个参数表示请求采用异步还是同步方式,
默认值为true–异步方式
-
作用
使用Ajax最直观的感受是向服务器获取新数据不需要刷新页面等待
了,良好的用户体验
2: 前后端开发联调需要注意哪些事情?后端接口完成前如何 mock 数据?
- 注意点:
-
约定数据
:需要传输的数据以及数据类型; -
约定接口
:接口名称,请求和响应的格式,请求的参数名称,响应的数据格式; -
约定方式
:是get还是post,后端用同样的方式接收发送过来的数据 - 前后端独立开发,前端向Mock Server发送请求,获取模拟的数据进行
开发和测试
- 如果接口修改了,Mock Server要
同步修改
-
如何 mock ?
方法一
:本地Mock Server做法:前端把Mock Server克隆到本地,开发的时候,开启前端工程服务器和Mock Server,所有的请求都发向本地服务器,获取到Mock数据.
方法二
: 使用nodejs的express框架
3:点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?
- 1.在请求数据方法前引入布尔变量如
var isDataArrive = true
,
2.在绑定按钮点击请求数据事件的方法里的开头做次判断,如果发请求前有值(即isDataArrive = ture
),就return,不请求,因为在
3.在xhr.onreadystatechange方法里的判断xhr.readystate的值===4的方法里引入布尔变量isDataArrive = true
,
4.在发送请求的方法xhr.send()后引入布尔变量isDataArrive = false
.
var check = true;
btn.addEventListener("click",function(){
if(!check){
return;
}
var xhr=new XMLHttpRequest()
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&(xhr.status==200||xhr.status==304)){
console.log(xhr.response);
check = true;
}
}
xhr.open(method,url,true);
xhr.send();
check=false
})
4:封装一个 ajax 函数,能通过如下方式调用。后端在本地使用server-mock来 mock 数据
<script>
//封装的方法
function ajax(opts){
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 304){
var results = JSON.parse(xhr.responseText)
opts.success('results')
}else{
opts.error()
}
}
}
var query = '?'
for (key in opts.data){
query += key + '=' + opts.data[key] + '&'
//query = query + key + '=' + opts.data[key] + '&'
//?username=xiaoming& 遍历第一次
//?username=xiaoming&password=abcd1234& 第二次
}
query = query.substr(0, query.length-1)//去除最后一位的&--->?username=xiaoming&password=abcd1234
xhr.open(opts.type, opts.url+query, true)//配置参数,这里 opts.url+query = '/login?username=xiaoming&password=abcd1234'
xhr.send()//发生请求
}
//点击事件
document.querySelector('#btn').addEventListener('click', function () {
ajax({
url: '/login',//接口地址
type: 'get', // 类型, post 或者 get,
data: {
username: 'xiaoming',
password: 'abcd1234'
},
success: function (ret) {
console.log(ret); //ret为xhr.responseText,成功请求到的内容
},
error: function () {
console.log('出错了')
}
})
});
</script>
5:实现加载更多的功能,效果范例,后端在本地使用server-mock来模拟数据
- 效果
HTML__CSS部分
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>
加载更多
</title>
<style>
ul,
li {
margin: 0;
padding: 0
}
#ct li {
list-style: none;
border: 1px solid #ccc;
padding: 10px;
margin-top: 10px;
cursor: pointer;
}
#load-more {
display: block;
margin: 10px auto;
text-align: center;
cursor: pointer;
}
.btn {
display: inline-block;
height: 40px;
line-height: 40px;
width: 80px;
border: 1px solid #E27272;
border-radius: 3px;
text-align: center;
text-decoration: none;
color: #E27272;
}
.btn:hover {
background: green;
color: #fff;
}
#ct>li:hover {
background-color: pink;
}
</style>
</head>
<body>
<ul id="ct">
</ul>
<a id="load-more" class="btn" href="#">
加载更多
</a>
</body>
</html>
js部分
<script>
var ct = document.querySelector('#ct')
var btn = document.querySelector('#load-more')
var curIndex = 0 //当前要加载的数据的序号
var len = 5 // 每次加载多少个数据
var isLoading = false //状态锁,用于判断是否在加载数据
//点击事件
btn.addEventListener('click', function (e) {
e.preventDefault(); //防止点击 a 链接页面跳到顶部
if (isLoading) {
return //如果正在请求数据,那这次点击什么都不做
}
//执行到这里说明 没有正在发出的请求,那后面就可以发请求
ajax('/loadMore', {
idx: curIndex,
len: len
}, function (data) {
appendData(data)
isLoading = false //数据到来之后 解
curIndex = curIndex + len //修改序号,下次要数据就从新序号开始要
console.log(curIndex)
})
isLoading = true //发请求之前做个标记加锁
})
//封装的函数
function ajax(url, json, onSuccess, onError) {
var xhr = new XMLHttpRequest()
var arr = []
for (key in json) {
arr.push(key + '=' + json[key])
}
url += '?' + arr.join('&')
xhr.open('get', url)
xhr.send()
xhr.onload = function () {//若xhr请求成功,就会触发xhr.onreadystatechange和xhr.onload两个事件。 那么我们到底要将成功回调注册在哪个事件中呢?我倾向于 xhr.onload事件,因为xhr.onreadystatechange是每次xhr.readyState变化时都会触发,而不是xhr.readyState=4时才触发
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
onSuccess(JSON.parse(this.response))//this = xhr对象 this.response 是 responseText
} else {
onError && onError()
}
}
}
//封装函数,data 为 JSON.parse(this.response)即响应内容
function appendData(data) {
for (var i = 0; i < data.length; i++) {
var child = document.createElement('li')
child.innerText = data[i]
ct.appendChild(child)
}
}
function onError() {
console.log('出错了')
}
</script>
后端部分:router.js
app.get('/loadMore', function (req, res) {
var curIdx = req.query.idx//通过query去拿,这里的idx对应前端js发生请求的参数idx
var len = req.query.len
var data = []
for (var i = 0; i < len; i++) {
data.push('头条' + (parseInt(curIdx) + i))
}
res.send(data);
});