1.ajax 是什么?有什么作用?
Ajax是Asynchronous JavaScript and XML的缩写,这一技术能够向服务器请求额外的数据而无需卸载整个页面,会带来良好的用户体验。传统的HTTP请求流程大概是这样的:
- 浏览器向服务器发送请求
- 服务器根据浏览器传来数据生成response
- 服务器把response返回给浏览器
- 浏览器刷新整个页面显示最新数据
- 这个过程是同步的,顺序执行
异步数据传输(HTTP 请求)从服务器获取数据
无需重新加载页面
通过DOM操作网页部分更新
网页没有缓存
有安全问题
2.
- 前后端开发联调需要注意哪些事情?
1:get/post; //请求类型
2./loadMore; //接口位置
3.{
index: 3, //请求的数组的序号和长度
length: 5
};
4.['new1', 'news2'...'news5']; //需要的数据,JSON格式的数组
- 后端接口完成前如何 mock 数据?
1.自己模拟数据来进行MOCK;
2.使用server-mock或mock.js搭建模拟服务器,进行模拟测试;
3.使用XAMPP等工具,编写PHP文件来进行测试。
xhr.open('get', '/loadmore?index='+pageIndex+'&length=5', true)
/*生成请求
*将接口和数据的要求
*通过字符串拼接出来
*/
xhr.send() /*发送
3.点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?
/*
var isDataArrive = true * 添加一个变量来记录数据到来状态
* 初始状态为true
*/
btn.addEventListener('click', function(){
if(!isDataArrive){
return;
}
xhr.onreadystatechange = function(){
...
if(xhr.readyState === 4){
... /*
isDateArrive = true * 在onreadystatechange事件变为4之后
} * 表示请求的数据正常生成
} */
xhr.open()
xhr.send() /*
* 到达这里表示数据已正常到来
isDateArrive = false * 状态改变--->false
* 之后重复点击不会再生成请求发送
*/
})
4.封装一个 ajax 函数,能通过如下方式调用。后端在本地使用server-mock来 mock 数据
//ajax封装
function ajax(opts){
opts.success = opts.success || function(){}; //该项内容用户没有输入则设置默认
opts.error = opts.error || function(){};
opts.dataType = opts.dataType || 'json';
opts.data = opts.data || {};
var dataStr = '';
for (var key in opts.data){
dataStr += key + '=' + opts.data[key] + '&'
}
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200 || xmlhttp.status ==304) {
if(opts.dataType === 'text'){
opts.success(xmlhttp.responseText);
}
if(opts.dataType === 'json'){
var json = JSON.parse(xmlhttp.responseText);
opts.success(json)
}
}else{
opts.error()
}
}
}
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();
}
}
document.querySelector('#btn').addEventListener('click', function(){
ajax({
url: '/login', //接口地址
type: 'get', // 类型get
data: {
username: 'xiaoming',
password: 'abcd1234'
},
success: function(ret){
console.log(ret); // {status: 0}
},
error: function(){
console.log('出错了')
}
})
});
5.
加载更多
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<style type="text/css">
ul,li{
margin: 0;
padding: 0;
}
li:hover{
background-color: #6ff;
color: #fff;
}
.btn{
display:block;
margin: 10px auto;
text-decoration: none;
color: #fff;
background: #6ea;
width: 100px;
padding: 10px;
line-height: 30px;
font-size: 18px;
text-align: center;
}
#ct>li{
padding: 10px;
margin: 10px 0;
border: 1px solid #ccc;
}
</style>
<body>
<ul id="ct">
<li>内容1</li>
<li>内容2</li>
</ul>
<a href="#" id="load-more" class="btn">加载更多</a>
<script type="text/javascript">
var btn = document.querySelector(".btn")
var ct = document.querySelector("#ct")
var pageIndex = 3
var isDataArrive = true
btn.addEventListener('click',function(e){
e.preventDefault()
if(!isDataArrive){
return;
}
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 304){
var results = JSON.parse(xhr.responseText)
console.log(results)
var fragment = document.createDocumentFragment()
for (var i = 0;i<results.length;i++){
var node = document.createElement('li')
node.innerText = results[i]
fragment.appendChild(node)
}
ct.appendChild(fragment)
pageIndex = pageIndex + 5
}else{
console.log('出错了')
}
isDataArrive = true
}
}
xhr.open('get','/loadMore?index='+pageIndex+'&length=5',true)
xhr.send()
isDataArrive = false
})
</script>
</body>
</html>
//router.js
app.get('/loadMore', function(req, res){
var curIdx = req.query.index
var len = req.query.length
var data = []
for(var i =0; i<len; i++){
data.push('内容' + (parseInt(curIdx) + i) )
}
setTimeout(function(){
res.send(data);
},5000)
// res.send(data);
});
//完整的ajax封装
<script>
var btn = document.querySelector(".btn")
var ct = document.querySelector("#ct")
var pageIndex = 3
var isDataArrive = true //上锁
btn.addEventListener('click',function(e){
e.preventDefault()
if(!isDataArrive) return;
load(function(e){
renderPage(e)
pageIndex = pageIndex + 5
isDataArrive = true //解锁
})
isDataArrive = false //加锁
})
function load(callback){
ajax({
url:'/loadMore',
type: 'get',
dataType: 'json',
data: {
index: pageIndex,
length: 5
},
success: callback, //callback 是一个函数,得到的参数传给e
error: function(){
console.log('error');
}
})
}
function renderPage(text){
var fragment = document.createDocumentFragment()
for (var i = 0;i<text.length;i++){
var node = document.createElement('li')
node.innerText = text[i]
fragment.appendChild(node)
}
ct.appendChild(fragment)
}
function ajax(opts){
opts.success = opts.success || function(){}; //该项内容用户没有输入则设置默认的匿名函数
opts.error = opts.error || function(){};
opts.dataType = opts.dataType || 'json';
opts.data = opts.data || {};
var dataStr = '';
for (var key in opts.data){
dataStr += key + '=' + opts.data[key] + '&'
}
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200 || xmlhttp.status ==304) {
if(opts.dataType === 'text'){
opts.success(xmlhttp.responseText);
}
if(opts.dataType === 'json'){
var json = JSON.parse(xmlhttp.responseText);
opts.success(json)
}
}else{
opts.error()
}
}
}
dataStr = dataStr.substr(0,dataStr.length-1);
if (opts.type.toLowerCase() === 'post') {
xmlhttp.open(opts.type, opts.url,true);
xmlhttp.setRequestHeader('contengt-type', 'application/x-www-form-urlencoded')
xmlhttp.send(dataStr); //post的传递请求方式
}
if (opts.type.toLowerCase() === 'get') {
xmlhttp.open(opts.type, opts.url+'?'+dataStr,true);
xmlhttp.send();
}
}
</script>

网友评论