1.ajax 是什么?有什么作用?
Asynchronous JavaScript and XML(異步的 JavaScript 和 XML 通過在后臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
作用:
- 更新數據而不需要刷新頁面: 它能在不刷新整個頁面的前提下與服務器通信維護數據,由于ajax是按照需求請求數據,避免發送那些沒有改變的數據。
- 異步通信: 它與服務器使用異步的方式通信,不會打斷用戶的操作(卡死頁面)。
- 前后端負載平衡: 可以將后端服務器的一些工作轉移給客戶端,利用客戶端限制的能力來處理,減輕了服務器的負擔。
- 數據與呈現分離: 利于分工,降低前后耦合。
缺點 - 瀏覽器歷史記錄的遺失: 在使用AJAX對頁面進行改變后,由于并沒有刷新頁面,沒有改變頁面的訪問歷史,當用戶想要回到上一個狀態時,無法使用瀏覽器提供的后退。
- AJAX的安全問題: AJAX的出現就像建立起了一直通服務器的另一條通道,容易遭受到一些攻擊
2.前后端開發聯調需要注意哪些事情?后端接口完成前如何 mock 數據?
注意事項:
約定數據:有哪些需要傳輸的數據,數據類型是什么;
約定接口:確定接口名稱及請求和響應的格式,請求的參數名稱、響應的數據格式;
根據這些約定整理成接口文檔
如何mock數據:
1.自己模擬數據來進行MOCK;
2.使用server-mock或mock.js搭建模擬服務器,進行模擬測試;
3.使用XAMPP等工具,編寫PHP文件來進行測試。
3.點擊按鈕,使用 ajax 獲取數據,如何在數據到來之前防止重復點擊?
1.初始化數據是已經響應成功 var isDataArrive = true
2.當剛剛發送請求時,立即將再次發送封鎖,防止用戶多次點擊
xhr.open(type,url ,true);
xhr.send();
isDataArrive = false
btn.addEventListener("click",function(){
if(!isDataArrive){
return;
}
...
}
3.當服務器響應完成,返回數據后,立即設置 isDataArrive = true
,這樣用戶再次點擊就可以重新發送請求了
var isDataArrive = true;//1
btn.addEventListener("click",function(){
if(!isDataArrive){
return;
} //3
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status ===200 || xhr.status ===304){
//do something
}else{
//do something
}
isDataArrive = true //4
}
};
xhr.open(type,url ,true);
xhr.send();
isDataArrive = false; //2
})
4.封裝一個 ajax 函數,能通過如下方式調用。后端在本地使用server-mock來 mock 數據
function ajax(opts){
opts.success = opts.success || function(){};
opts.error = opts.error || function(){};
opts.type = opts.type || 'get';
opts.dataType = opts.dataType || 'json';
opts.data = opts.data || {};
var dataStr = '';
for(var key in opts.data){
dataStr += key+ '='+opts.data[key] + '&';
}
dataStr = dataStr.substr(0,dataStr.length-1);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 ){
if(xhr.status === 200 || xhr.status ===304){
if(opts.dataType === 'text'){
opts.success(xhr.responseText)
}
if(opts.dataType === 'json'){
var json =JSON.parse(xhr.responseText);
opts.success(json)
}
}else{
opts.error()
}
}
};
if(opts.type.toLowerCase() === 'get'){
xhr.open(opts.type,opts.url+'?'+dataStr,true);
xhr.send();
}
if(opts.type.toLowerCase() === 'post'){
xhr.open(opts.type,opts.url,true);
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
xhr.send(dataStr)
}
}
5.實現加載更多的功能,效果范例,后端在本地使用server-mock來模擬數據
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>加載更多</title>
<style>
.container {
list-style: none;
margin: 0;
padding: 0;
}
.container li {
border: 1px solid #cccccc;
padding: 10px;
margin-bottom: 10px;
}
.container li:hover{
background: green;
color: #ffffff;
}
#btn{
text-align: center;
text-decoration: none;
color: #e27272;
border: 1px solid #e27272;
border-radius: 3px;
display: block;
margin: 0 auto;
width: 80px;
height: 40px;
line-height: 40px;
}
#btn img{
width: 40px;
height: 40px;
}
</style>
</head>
<body>
<ul class="container">
<li>內容1</li>
<li>內容2</li>
</ul>
<a href="#" id="btn">加載更多</a>
<script>
var btn = document.getElementById("btn");
var ct = document.querySelector(".container");
var idx = 3;
var isDataArr = true;
btn.addEventListener("click",function(e){
e.preventDefault();
if(isDataArr===false){
return;
}
btn.innerHTML = "";
ajax({
url: "/loadMore",
type: "get",
data: {
index: idx,
length: 5
},
success: function(data){
var fragment = document.createDocumentFragment();
for(var i = 0; i < data.length; i++){
var node = document.createElement("li");
node.innerText = data[i];
fragment.appendChild(node);
}
ct.appendChild(fragment);
btn.innerHTML = "加載更多";
idx += 5;
},
error: function(){
console.log("加載失敗")
}
});
});
function ajax(opts){
opts.success = opts.success || function(){};
opts.error = opts.error || function(){};
opts.type = opts.type || 'get';
opts.dataType = opts.dataType || 'json';
opts.data = opts.data || {};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 ){
if(xhr.status === 200 || xhr.status ===304){
if(opts.dataType === 'text'){
opts.success(xhr.responseText)
}
if(opts.dataType === 'json'){
var json =JSON.parse(xhr.responseText);
opts.success(json)
}
}else{
opts.error()
}
}
isDataArr = true;
};
var dataStr = '';
for(var key in opts.data){
dataStr += key+ '='+opts.data[key] + '&';
}
dataStr = dataStr.substr(0,dataStr.length-1);
if(opts.type.toLowerCase() === 'get'){
xhr.open(opts.type,opts.url+'?'+dataStr,true);
xhr.send();
}
if(opts.type.toLowerCase() === 'post'){
xhr.open(opts.type,opts.url,true);
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
xhr.send(dataStr)
}
isDataArr = false;
}
</script>
</body>
</html>
后臺代碼
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)
},1000)
});