問答
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 饑人谷"http://回參中的值
})
})
- 使用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('出錯了')
}
});
});