js原生ajax
AJAX
準備工作-伺服器環境的搭建
ajax可以在本地使用,但是牽扯到不同源問題,需要跨域操作。下面是兩個檔案的程式碼,test.html放在桌面上,cors.php放在搭好的伺服器上面,我這裡配置的埠號是9096,埠號可以自行配置,預設的話是80埠,雙擊開啟test.html檔案,控制檯會輸出下面資訊
{"code":200,"msg":"success"}
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script>
$.get("http://localhost:9096/testCode/cors/cors.php" ).done(function(data){
console.log(data)
})
</script>
</body>
</html>
cors.php
<?php
header("access-control-allow-origin: *");
$result = array(
'code' => 200,
'msg' => 'success'
);
if($_GET['callback'])
echo ';'. $_GET['callback'] . '(' . json_encode($result) .')';
else
echo json_encode($result);
?>
對上面這些不懂得可以直接忽略,不影響下面學習,學習ajax最好在本地配置一個伺服器,將程式碼放在伺服器下面對應的資料夾中通過127.0.0.1或者localhost或者配置虛擬主機來訪問。
最簡單的辦法是在網上下載一個整合的環境,我們以php語言和apache服務為例,比如整合環境phpstudy、wamp等,愛鼓搗的碼友可以自己動手一步一步的配置。我本地使用的是phpstudy整合環境,安裝使用都比較方便,也不大才35.6M。
溫馨提示:看到這裡的預設已經在本地搭建好伺服器,並將埠號配置為9096,如果沒有配置埠號將下面的9096替換為80或者省去即可。下面的程式碼均放在伺服器下面通過127.0.0.1或者localhost或者配置虛擬主機來訪問。
什麼是Ajax
全稱 Asynchronous JavaScript and XML (非同步JavaScript和XML)
用JavaScript非同步的形式去操作xml,它要完成的工作也就是資料互動。
資料互動也就是可以從某個地方拿取資料,也可以傳送資料到某個地方。
一般情況下我們會使用ajax和後端(php、nodejs等)進行資料互動,我們會把資料傳送給後端,後端接收到資料後做出一些操作後返回一些資料給我們,這就是資料互動,ajax做的就是這一塊。
它有一個特點,就是體現在非同步互動上面,可以節約使用者時間,提高使用者體驗,減少資料請求等。
ajax可以在不重新整理頁面的情況下發送一個請求到某個地方獲取一些資料。
例子:這裡以一個靜態檔案作為例子,test.html與1.txt在同一級,都在伺服器下面的www目錄下,我們開啟瀏覽器,訪問localhost:9096/test.html,單擊按鈕將會請求同一目錄下1.txt檔案的內容,如果成功的話會彈出一個彈出框顯示hello,ajax!。
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
//ajax的整個流程可以理解為瀏覽器操作,比如:
var xhr = new XMLHttpRequest();//可以想象為開啟瀏覽器
xhr.open('get','1.txt',true);//在位址列輸入地址
xhr.send();//按下回車提交
//等待瀏覽器返回內容
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {//返回內容
if(xhr.status == 200){//200成功狀態碼
alert(xhr.responseText);
}else{
alert('出錯了,Err:' + xhr.status );
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按鈕" id="btn">
</body>
</html>
1.txt
hello,ajax!
建立Ajax物件
- 建立一個ajax物件,上面的new XMLHttpRequest()適用通用瀏覽器,ie6以下是new ActiceXObject(‘Microsoft.XMLHttp’),對此我們需要解決相容性問題。
//方法一:
var xhr = null;
if(window.XMLHttpRequest{
xhr = new XMLHttpRequest();
}else{
xhr = new ActiceXObject('Microsoft.XMLHTTP');
}
//方法二:
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
資料的請求
open方法有三個引數
開啟方式,也就是請求方式(get、post等,其他的可以在網上找一下)
- get
- 把資料名稱和資料值用等號(=)連線,如果有多個的話,那麼它會把多個數據組合用&進行連線,然後把資料放到url?後面傳到指定頁面
- url長度限制的原因,我們不要通過get方式傳遞過多的資料
- post
- 理論上無限制,實際上我們可以通過改變php.ini配置檔案中的post_max_size來限制傳送資料的大小
- get
請求地址
- 資料提交的地址,預設是當前頁面
是否非同步
- 非同步:非阻塞,前面的程式碼不會影響後面程式碼的執行
- 同步:阻塞,前面的程式碼會影響後面程式碼的執行
setRequestHeader方法
- xhr.setRequestHeader(‘content-type’,’application/x-www-form-urlencoded’);//申明發送的資料型別
send方法
- get請求的send方法無需引數,例如:xhr.send();get請求的資料放在url中,例如
xhr.open('get','get.php?username=zhou&age=21',true);
- post請求的資料放在send方法裡面,例如:
xhr.send('username=zhou&age=21');
資料的獲取
onreadystatechange事件: (on readystate change)當readyState改變的時候觸發
readyState : ajax工作狀態
- 0 (未初始化)物件已經建立,但還沒有呼叫open()方法
- 1 (啟動)已經呼叫open() 方法,但尚未呼叫send()方法傳送請求
- 2 (傳送)send()方法已呼叫,請求已經發送完成,但尚未接收到響應
- 3 (接收)已經接收到部分響應資料
- 4 (完成)已經接收到了全部資料,而且已經可以在客戶端使用了
status : 伺服器狀態,http狀態碼
responseText : ajax請求返回的內容就被存放到這個屬性下面
下面是一個例子,text.html和get.php在伺服器下同一級
下面用到了PHP中的json_encode函式,和JS中的JSON.parse()方法,意義在於將這些資料統一轉換為json格式。
text.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
//建立物件
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
xhr.open('get','get.php',true);
xhr.send();//傳送請求
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if(xhr.status == 200){//成功
alert(JSON.parse(xhr.responseText));
}else{
alert('出錯了,Err:'+xhr.status);
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按鈕" id="btn">
</body>
</html>
get.php
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);// 關閉錯誤報告
$arr = array('zhou','21','男');
echo json_encode($arr);
get請求
get請求有時可能會有快取和亂碼問題,在下面有相應解決方案
例子:
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
xhr.open('get','get.php?username=zhou&age=21',true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if(xhr.status == 200){
alert(JSON.parse(xhr.responseText));
}else{
alert('出錯了,Err:'+xhr.status);
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按鈕" id="btn">
</body>
</html>
get.php
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);
$username = $_GET['username'];
$age = $_GET['age'];
echo json_encode("$username,$age");
get請求的響應預設是可以快取的(響應應該包含一個到期時間, 或者有一個驗證器),get請求被快取,導致頁面資料沒有重新整理,我們有時候需要針對快取問題有一個解決方案:
- 快取問題,在url?後面連結一個隨機數,這裡使用時間戳
xhr.open('get','get.php?username=zhou&age=21&'+new Date().getTime(),true);
- 亂碼問題,使用encodeURI對資料進行編碼
xhr.open('get','get.php?username='+encodeURI('周')+'&age=21&'+new Date().getTime(),true);
post請求
- post必須要告訴後端傳送的資料是什麼型別的,然後後端才能按照這個型別來解析資料,如果不告訴後端傳送的是什麼型別,後端將不解析。
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');//post必須要告訴後端傳送的資料是什麼型別的
- post方式,資料放在send()裡面作為引數傳遞
xhr.send('username=zhou&age=21');
- post和get不一樣,post沒有快取問題,post用來提交資料,是沒有快取的,get一般用來的到資料,可能存在快取問題。這跟ajax沒有關係,跟web機制有關係。
- post沒有亂碼問題,因為在傳送資料的時候已經聲明瞭傳送的資料是什麼型別的,所以在傳送資料的時候自動幫你把資料進行編碼,比如下面這個,在傳送資料的時候自動對資料進行url編碼,所以說無需在對資料進行編碼。
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
post請求的例子:
text.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
xhr.open('post','post.php',true);
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');//post必須要告訴後端傳送的資料是什麼型別的
xhr.send('username=zhou&age=21');
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if(xhr.status == 200){
alert(JSON.parse(xhr.responseText));
}else{
alert('出錯了,Err:'+xhr.status);
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按鈕" id="btn">
</body>
</html>
post.php
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);
$username = $_POST['username'];
$age = $_POST['age'];
echo json_encode("$username,$age");