AJAX的請求方式
AJAX
AJAX簡介
AJAX全稱為Asynchronous JavaScript And XML,就是非同步的 JS 和 XML。
通過AJAX可以在瀏覽器中向伺服器傳送非同步請求,最大的優勢:無重新整理獲取資料。AJAX不是新的程式語言,而是一種將現有的標準組合在一起使用的新方式。
XML簡介
XML可擴充套件標記語言。
XML被設計用來傳輸和儲存資料。
XML和 HTML類似,不同的是HTML中都是預定義標籤,而xML中沒有預定義標籤,全都是自定義標籤,用來表示一些資料。
比如說我有一個學生資料:
name ="孫悟空"; age= 18 ; gender = "男";
用XML表示:
<student>
<name>孫悟空</name>
<age>18</age>
<gender>男</gender>
</student>
AJAX的特點
AJAX的優點
可以無需重新整理頁面而與伺服器端進行通訊。
允許你根據使用者事件來更新部分頁面內容。
AJAX的缺點
沒有瀏覽歷史,不能回退
存在跨域問題(同源)
SEO 不友好
AJAX的使用
HTTP
HTTP (hypertext transport protocol)協議『超文字傳輸協議』,協議詳細規定了瀏覽器和全球資訊網伺服器之間互相通訊的規則。
請求報文
重點是格式與引數
行 POST /s?ie=utf-8 HTTP/1.1 頭 Host: atguigu.com Cookie: name=guigu Content-type: application/x-www-form-urlencoded User-Agent: chrome 83 空行 體 username=admin&password=admin
響應報文
行 HTTP/1.1 280 oK
頭 Content-Type: text/html; charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
體 <html>
<head></head>
body>
<h1>蘇槿年</h1>
</body>
</html>
引入express
//1.引入express
const express = require( 'express' );
//2.建立應用物件
const app = express();
//3.建立路由規則
// request是對請求報文的封裝
// response是對響應報文的封裝
app.get( '/server ' , (request, response)=>{
//設定響應頭設定允許跨域
response. setHeader( ' Access-Control-Allow-Origin', '*');
//設定響應體
response.send( 'HELLO AJAX');
});
//4.監聽埠啟動服務
app.listen( 8000,()=>{
console.log("服務已經啟動,8000埠監聽中....");
});
AJAX請求格式
GET請求
//繫結事件
btn.onclick = function(){
//1.建立物件
const xhr = new XMLHttpRequest();
//2.初始化設定請求方法和url
xhr.open( ' GET', "http://127.0.0.1 :8000/server' );
//3.傳送
xhr.send();
//4.事件繫結處理服務端返回的結果
// on when當....時候
// readystate 是 xhr物件中的屬性,表示狀態日1 2 3 4
// change 改變
xhr.onreadystatechange = function(){
//判斷(服務端返回了所有的結果)
if(xhr.readyState === 4){
//判斷響應狀態碼200 404 403 401 500
// 2xx 成功
if(xhr.status >= 200 && xhr.status < 300){
//處理結果 行 頭 空行 體
//響應
// console.log(xhr.status);//狀態碼
// console.log(xhr.statusText);//狀態字串
// console.log(xhr.getAllResponseHeaders());//所有響應頭
// console.log(xhr.response);//響應體
//設定result的文字
result.innerHTML = xhr.response;
}else{
}
}
}
POST請求
//獲取元素物件
const result = document.getElementById( "result");
//繫結事件
result.addEventListener( "mouseover", function(){
//1.建立物件
const xhr = new XMLHttpRequest();
//2.初始化設定型別與URL
xhr.open( 'POST', 'http://127.0.0.1:8000/server');
//設定請求頭
xhr.setRequestHeader('Content-Type' , 'application/x-www-form-urlencoded')
xhr.setRequestHeader( ' name ' , 'sujinnian');
//3.傳送
xhr.send('a=100&b=200&c=300');//請求體,請求資料,任意格式,任何形式
//xhr.send('a:100&b:200&c:300');
//xhr.send('123456');
//4.事件繫結
xhr.onreadystatechange = function(){
//判斷
if(xhr.readyState == 4){
if(xhr.status >= 200 && xhr.status < 300){
//處理服務端返回的結果
result.innerHTML = xhr.response;
}
}
}
});
服務端響應JSON資料
//繫結事件
btn.onclick = function(){
//1.建立物件
const xhr = new XMLHttpRequest();
//2.初始化設定請求方法和url
xhr.open( ' GET', "http://127.0.0.1 :8000/server' );
//3.傳送
xhr.send();
//4.事件繫結處理服務端返回的結果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
//console.log(xhr.response);
//result.innerHTML = xhr.response;
//手動對資料轉化
//let data = JSON.parse(xhr.response);
//console.log(data);
//result.innerHTML = data.name;
//自動轉換
console.log(xhr.response);
result.innerHTML = xhr.response;
}
}
}
AJAX請求超時與網路錯誤
//繫結事件
btn.onclick = function(){
const xhr = new XMLHttpRequest();
//超時設定2s 設定
xhr.timeout = 2000;
//超時回撥
xhr.ontimeout = function(){
alert("網路異常,請稍後重試!!");
}
//網路異常回調
xhr.onerror = function(){
alert("你的網路似乎出了一些問題!")
}
xhr.open('GET', "http://127.0.0.1 :8000/server' );
//3.傳送
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
result.innerHTML = xhr.response;
}
}
}
AJAX請求取消
//獲取元素物件
const btns = document.querySelectorAl1 ( ' button ' );
let x = null;
btns[e].onclick = function(){
x = new XMLHttpRequest();
x.open( "GET", "http://127.0.0.1:8000/delay");
x.send();
}
// abort;請求取消
btns[1].onclick = function(){
x.abort();
}
AJAX請求重複傳送問題
//獲取元素物件
const btns = document.querySelectorAl1("button");
let x = null;
//標識變數
let issending = false;//是否正在傳送AJAX請求
btns[e].onclick = function(){
//判斷標識變數
if(isSending) x.abort();// 如果正在傳送,則取消該請求,建立一個新的請求
x=new XMLHttpRequest();
//修改標識變數的值
isSending = true;
x.open("GET", 'http://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange = function(){
if(x.readyState ===4){
//修改標識變數
isSending = false;
}
}
}
jQuery中的AJAX
<div class="container">
<h2 class="page-header">jQuery傳送AJAX請求</h2>
<button class="btn btn-primary" >GET</button>
<button class="btn btn-danger " >POST</button>
<button class="btn btn-info">通用型方法ajax</button>
</div>
<script>
//$.get('url',{引數},方法,資料型別)
$('button').eq(0).click(function(){
$.get('http://127.0.0.1:8000/jquery-server' , {a:100, b:200},function(data){
console.log(data);
},'json');
})
$('button').eq(1).click(function(){
$.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200},function(data){
console.log(data);
});
})
</script>
通用方法
$.ajax({
//url
url:'http://127.0.0.1:8080/jquery-server',
//引數
data: {a: 100, b:200},
//請求型別
type:'GET',
//響應體結果
dataType:'json',
//成功的回撥
success: function(data){
console.log(data);
},
//超時時間
timeout: 2000,
//失敗的回撥
error: function(){
console.log('出錯啦!!');
},
//頭資訊
headers:{
c:300,
d:400
}
})
Axios傳送AJAX請求
const btns = document.querySelectorA11('button');
//配置baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8080';
btns[0].onclick = function(){
//GET 請求
axios.get('/axios-server' , {
// url引數
params: {
id:100,
vip:7
},
//請求頭資訊
headers: {
name:'sujinnian',
age: 20
}
}).then(value => {
console.log(value);
})
}
fetch函式傳送AJAX請求
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
//請求方法
method: "POST',
//請求頭
headers:{
name:'sujinnian'
},
//請求體
body:'username=admin&password=admin'
}).then(response => {
// return response.text();
return response.json();
}).then(response=>{
console.log(response);
});
}
跨域
同源策略
同源:協議、域名、埠號 必須完全相同。
違背同源策略就是跨域。
如何解決跨域
JSONP
- JSONP是什麼
JSONP(JSON with Padding),是一個非官方的跨域解決方案,純粹憑藉程式設計師的聰明才智開發出來,只支援get請求。
- JSONP怎麼工作的?
在網頁有一些標籤天生具有跨域能力,比如: img link iframe script。JSONP就是利用script標籤的跨域能力來發送請求的。
- JSONP的使用
1.動態的建立一個script標籤
var script = document.cteateElement("script");
2設定script的src,設定回撥函式
script.src = "http://localhost:3000/testAlAX?callback=abg";
原生jsonp的實現
//獲取input元素
const input = document.querySelector('input');
const p = document.querySelector('p');
//宣告 handle 函式
function handle(data){
input.style.border = "solid 1px #f00";
//修改p標籤的提示文字
p.innerHTML = data.msg;
}
//繫結事件
input.onblur = function(){
//獲取使用者的輸入值
let username = this.value;
//向伺服器端傳送請求檢測使用者名稱是否存在
//1.建立script標籤
const script = document.createElement('script');
//2.設定標籤的src屬性
script.src = 'http://127.0.0.1:8000/check-username';
//3.將script插入到文件中
document.body.appendChild(script);
}
jQuery傳送jsonp請求
$('button').eq(0).click(function(){
$.getJsoN('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){
$('#result').html(`
//data屬性
`)
});
}
CORS
CORS是什麼?
CORS(Cross-Origin Resource Sharing),跨域資源共享。CORS是官方的跨域解決方案,它的特點是不需要在客戶端做任何特殊的操作,完全在伺服器中進行處理,支援get和 post 請求。跨域資源共享標準新增了一組HTTP首部欄位,允許伺服器宣告哪些源站通過瀏覽器有許可權訪問哪些資源
CORS 怎麼工作的?
CORS是通過設定一個響應頭來告訴瀏覽器,該請求允許跨域,瀏覽器收到該響應以後就會對響應放行。
CORS的使用
請求方式使用下列方法之一:
- GET
- HEAD
- POST
HTTP Headers 匹配下面的
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type, 但值是其中的一種:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
HTTP請求:
POST /cors HTTP/1.1
Origin:http://api.bob.com
Host: api.bob.com
有效的伺服器CORS響應:
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
CORS欄位介紹:
(1)Access-Control-Allow-Methods
該欄位必需,它的值是逗號分隔的一個字串,表明伺服器支援的所有跨域請求的方法。注意,返回的是所有支援的方法,而不單是瀏覽器請求的那個方法。這是為了避免多次"預檢"請求。
(2)Access-Control-Allow-Headers
如果瀏覽器請求包括Access-Control-Request-Headers欄位,則Access-Control-Allow-Headers欄位是必需的。它也是一個逗號分隔的字串,表明伺服器支援的所有頭資訊欄位,不限於瀏覽器在"預檢"中請求的欄位。
(3)Access-Control-Allow-Credentials
該欄位與簡單請求時的含義相同。
(4)Access-Control-Max-Age
該欄位可選,用來指定本次預檢請求的有效期,單位為秒。上面結果中,有效期是20天(1728000秒),即允許快取該條迴應1728000秒(即20天),在此期間,不用發出另一條預檢請求。