问答
1. ajax 是什么?有什么作用?
Ajax是Asynchronous JavaScript and XML的缩写,这一技术能够向服务器请求额外的数据而无需卸载整个页面,会带来良好的用户体验。传统的HTTP请求流程大概是这样的,
- 浏览器向服务器发送请求
- 服务器根据浏览器传来数据生成response
- 服务器把response返回给浏览器
- 浏览器刷新整个页面显示最新数据
这个过程是同步的,顺序执行
AJAX 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求)从服务器获取数据
这里的异步是指脱离当前浏览器页面的请求、加载等单独执行,这意味着可以在不重新加载整个网页的情况下,通过JavaScript发送请求、接受服务器传来的数据,然后操作DOM将新数据对网页的某部分进行更新,使用Ajax最直观的感受是向服务器获取新数据不需要刷新页面等待了。
2. 前后端开发联调需要注意哪些事情?后端接口完成前如何 mock 数据?(npm install -g server-mock)
前后端联调是一种 真实业务数据和 本地mock数据之间来回切换以达到前后端分离架构下的不同开发速度时数据交换的一种方式方法
** 需要注意的事情有:**
- 约定前后端联调的时间。
- 约定双方需要传输的数据和接口,在接口文档中确定好参数的名称、格式等。
- 约定请求和响应的格式和内容。
什么是mock数据:就是html发送一个ajax的请求。这个请求到哪里去,然后后端如何去响应这个请求。后端去获取数据,并且定义接口;前端编写页面,并且和后端进行交互。
mock数据的方法有:
- 使用server-mock或mock.js (http://mockjs.com/ )搭建模拟服务器,进行模拟测试(优点是不需要熟练掌握后台PHP语言,采用熟悉的js语法);
步骤:
- 安装node.js,呼出cmd命令
- 选取一个文件夹,使用npm install -g server -mock进行全局安装
- 输入mock start可以启动一个web 服务器,他的根目录就是你选取的文件夹,启动完成之后,web服务器就可以展示了
- 浏览器输入localhost:8080就是你选取的文件夹
- 使用mock init会自动的在文件夹下生成3个文件
- 当html使用url对接口进行请求,会被router.js里相同的接口接受比如
app.get("/loadMore",function(req,res){
//接受名为loadMore的php的参数
res.send({status:0,//向html发出正确的回参
msg:"hello 饥人谷"//回参中的值
})
})
- 使用XAMPP等工具,编写PHP文件来进行测试。
3. 点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?
方法一:
使用button的disabled属性,配合setTimeout 0,使在数据到来之前按钮都不能被点击
el.addEventListener("click",function(){
this.disabled=true;
ajax();
setTimeout(this.disabled=false,0);
});
方法二:
可设置标记变量flag,初始时设置flag为true.在用户点击提交按钮后,判断flag是否为true,如果是则发送ajax请求,并把flag设置为false。 等服务端给出响应后再把flag设置为true;
var ready = true;
$('.add-more').on('click', function(){
...
if(!ready){
return;
}
ready = false;
$.ajax({
...
complete: function(){
ready = true;
}
});
});
代码题
1. 封装一个 ajax 函数,能通过如下方式调用
function ajax(opts){
// todo ...
}
document.querySelector('#btn').addEventListener('click', function(){
ajax({
url: 'getData.php', //接口地址
type: 'get', // 类型, post 或者 get,
data: {
username: 'xiaoming',
password: 'abcd1234'
},
success: function(ret){
console.log(ret); // {status: 0}
},
error: function(){
console.log('出错了')
}
})
});
- 先写出未封装的普通的Ajax代码:
<!-- 需求是,在输入框输入用户名,点击按钮,打包请求后发给后台,后台响应对应的性别和年龄 -->
<input type="text" name="username" id="username" placeholder="请输入用户名">
<button id="btn">获取信息</button>
<dl id="ct">
<!-- 后台获取数据后浏览器进行操作,添加html -->
</dl>
<script type="text/javascript">
document.querySelector('#btn').addEventListener('click',function(){
var xmlhttp = new XMLHttpRequest();
var username = document.querySelector('#username').value;
var url = 'ajax_simple.php'+'?username='+username;
//GET方式
// xmlhttp.open('GET',url,true);
// xmlhttp.send();
//POST方式:
xmlhttp.open('POST','ajax_simple.php',true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("username="+username);
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var userInfo = JSON.parse(xmlhttp.responseText);
dealwith(userInfo);
}
}
});
function dealwith(userInfo){
var str = '<dt>性别:</dt>';
str += '<dd>'+userInfo.sex+'</dd>';
str += '<dt>年龄:</dt>';
str += '<dd>'+userInfo.age+'</dd>';
document.querySelector('#ct').innerHTML = str;
}
</script>
php代码:
<?php
$username = $_POST['username'];
//$username = $_GET['username'];
if($username === 'kevin'){
$ret = array('sex'=>'男','age'=>23);
}elseif ($username === 'david') {
$ret = array('sex'=>'男', 'age'=>30);
}else{
$ret = array('sex'=>'女','age'=>18);
}
echo json_encode($ret);
?>
在本地虚拟主机上运行如下:
- 代码封装后:
function dealwith(userInfo){
var str = '<dt>性别:</dt>';
str += '<dd>'+userInfo.sex+'</dd>';
str += '<dt>年龄:</dt>';
str += '<dd>'+userInfo.age+'</dd>';
document.querySelector('#ct').innerHTML = str;
}
function ajax(opts){
var xmlhttp = new XMLHttpRequest();
var dataStr = '';
for( var key in opts.data){
dataStr += key + '=' + opts.data[key]+'&'
}
dataStr = dataStr.substr(0,dataStr.length-1);
if(opts.type.toLowerCase()==='post'){
xmlhttp.open(opts.type,opts.url,true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(dataStr);
}
if(opts.type.toLowerCase() === 'get'){
xmlhttp.open(opts.type,opts.url+'?'+dataStr,true);
xmlhttp.send();
}
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState ==4 && xmlhttp.status == 200){
var json = JSON.parse(xmlhttp.responseText);
opts.success(json);
}
if(xmlhttp.readyState == 4 && xmlhttp.status == 404){
opts.error();
}
};
}
document.querySelector('#btn').addEventListener('click',function(){
ajax({
url:'ajax_simple.php',
type:'post',
data:{
username:document.querySelector('#username').value,
password:document.querySelector('#password')
},
success:function(jsonData){
dealwith(jsonData);
},
error:function(){
console.log('出错了')
}
});
});