Ajax基礎(chǔ)使用詳解
app.post('/postcors',(request,response)=>{
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置所有協(xié)議、域名、端口、允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 指定端口允許跨域
response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8082');
// 響應(yīng)頭,允許所有的響應(yīng)頭類型
response.setHeader('Access-Control-Allow-Headers','*');
// 設(shè)置響應(yīng)體
const data = {
name:'cors JSON',
type:'POST JSON Type'
}
response.send(JSON.stringify(data));
});Ajax基礎(chǔ)
1.1ajax簡介
AJAX全稱是Asynchronous JavaScript And XML,就是異步的JS和XML
通過Ajax可以在瀏覽器中向服務(wù)器發(fā)送異步請求,最大的優(yōu)勢是:無刷新獲取數(shù)據(jù)。
Ajax不是新的編程語言,而是一種將現(xiàn)有的標(biāo)準(zhǔn)組合在一起使用的新方式。
1.2XML簡介
xml 可擴(kuò)展標(biāo)記語言
xml 被設(shè)計用來傳輸和保存數(shù)據(jù)
xml和HTML類似,,不同的是HTML中都是預(yù)定義標(biāo)簽;而XML中沒有預(yù)定義標(biāo)簽,全都是自定義標(biāo)簽,用來保存一些數(shù)據(jù)
最開始Ajax在進(jìn)行數(shù)據(jù)交換的時候,使用的格式就是XML,服務(wù)器端給瀏覽器返回結(jié)果時就是返回XML格式的字符串,前端的JS在接收到結(jié)果之后對XML格式的字符串進(jìn)行解析,把數(shù)據(jù)提取出來。
但是現(xiàn)在使用AJAX時候就不再使用XML了,而是換成了JSON格式,JSON相對于XML更加簡潔,在數(shù)據(jù)轉(zhuǎn)換方面也相對容易、更靈活。
<student>
<name>名字</name>
<age>年齡</age>
<gender></gender>
</student>1.3AJAX的特點
1.3.1AJAX的優(yōu)點
可以無需刷新頁面與服務(wù)器進(jìn)行通信允許你根據(jù)用戶事件來更新部分頁面內(nèi)容
1.3.2AJAX的缺點
沒有瀏覽歷史,不能回退存在跨域問題(同源)SEO(搜索引擎優(yōu)化)不友好,網(wǎng)頁爬蟲爬不到,源代碼(響應(yīng)體)第一次請求時沒有要請求內(nèi)容的信息,他是通過Ajax向服務(wù)端發(fā)請求,服務(wù)端返回結(jié)果,然后js動態(tài)創(chuàng)建到頁面中的,爬蟲爬不到數(shù)據(jù)。IE緩存問題:ie瀏覽器會對Ajax請求結(jié)果進(jìn)行緩存,把結(jié)果緩存起來;當(dāng)下一次再去請求數(shù)據(jù)時候,會到緩存里找,而不是服務(wù)器返回的最新的請求結(jié)果,這樣的話可能會影響結(jié)果,解決的辦法是在url?后面加一個時間戳,讓瀏覽器知道這是兩次不同的請求。
1.4HTTP協(xié)議
hypertext transport protocol 超文本傳輸協(xié)議,協(xié)議詳細(xì)規(guī)定了瀏覽器和萬維網(wǎng)服務(wù)器之間互相通信的規(guī)則。
協(xié)議就是一種約定、規(guī)則。主要約定了請求報文、響應(yīng)報文這兩塊的內(nèi)容。
請求報文
格式:
一個完整的HTTP請求報文
請求行:{
請求類型GET/POST URL路徑 HTTP協(xié)議版本1.0 / 1.1 / 2.0
}
請求頭:{
Host: baidu.com
Ciikie: name=baidu
Content-type: application/x-www-from-urlencoded //告知服務(wù)器我的請求體是什么類型的
User-Agent: chrome 83
}
空行:{}
請求體:{//如果是get請求,請求體是空的;如果是POST請求,請求體可以不為空
username=admin&password=admin
}
一個完整的HTTP響應(yīng)報文
行:HTTP/1.1 200 OK (協(xié)議版本 響應(yīng)狀態(tài)碼 響應(yīng)狀態(tài)字符串)
頭: Content-type:text/html;charset=utf-8 //類型 就是對響應(yīng)體內(nèi) 容進(jìn)行一些相關(guān)的描述
Content-length:2048 //長度
Content-encoding:gzip //壓縮方式
空行:必須要有
體: <html>
<body>
<h1> html響應(yīng)的內(nèi)容是放在了響應(yīng)的報文當(dāng)中,瀏覽器在接到結(jié)果之后會把響應(yīng)體結(jié)果提取出來,對內(nèi)容進(jìn)行解析,在頁面渲染并顯示
</h1>
</body>
</html>參數(shù):
1.4.1 Express
// 1. 引入express
const express = require('express');
// 2. 創(chuàng)建應(yīng)用對象
const app = express();
// 3. 創(chuàng)建路由規(guī)則 request是對請求報文的封裝 response是對響應(yīng)報文的封裝
app.get('/server',(request,response)=>{
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 設(shè)置響應(yīng)體
response.send('Hello 原生AJAX!');
});
// 4. 監(jiān)聽端口啟動服務(wù)
app.listen(8082,()=>{
console.log("服務(wù)已經(jīng)啟動8082端口監(jiān)聽中......");
})1.5AJAX的應(yīng)用
1.5.1原生Ajax GET請求
只需要四步:
- 創(chuàng)建XMLHttpRequest對象
const xhr = new XMLHttpRequest(); - 設(shè)置請求的方法和url
xhr.open('GET','//127.0.0.1:8082/server'); - 發(fā)送
xhr.send(); - 處理服務(wù)端返回的結(jié)果
xhr.onreadystatechange = function(){}
當(dāng)xhr對象里的readystate屬性改變時處理。
readyState四個值的意義
- 0 未初始化
- 1 open方法已經(jīng)調(diào)用完畢
- 2 send方法已經(jīng)調(diào)用完畢
- 3 服務(wù)端返回了部分結(jié)果
- 4 服務(wù)端返回了所有結(jié)果
<button id="btn">點擊發(fā)送請求</button>
<div id="result"></div>
<script>
const btn = document.getElementsByTagName("button")[0];
const result=document.getElementById("result");
btn.onclick=function(){
// ajax的操作
// 1. 創(chuàng)建對象,
const xhr = new XMLHttpRequest();
// 2. 設(shè)置請求的方法和url
xhr.open('GET','http://127.0.0.1:8082/server');
// 3. 發(fā)送
xhr.send();
// 4. 事件綁定,處理服務(wù)端返回的結(jié)果
// on==when. readystate是xhr對象中的屬性,表示狀態(tài) .change 改變會改變四次
// 0未初始化 1(open方法已經(jīng)調(diào)用完畢) 2(send方法已經(jīng)調(diào)用完畢) 3(服務(wù)端返回了部分結(jié)果) 4(服務(wù)端返回了所有結(jié)果)
xhr.onreadystatechange = function(){
// 判斷服務(wù)端是否返回了所有結(jié)果
if(xhr.readyState === 4){
//判斷響應(yīng)狀態(tài)碼
if(xhr.status >= 200 && xhr.status < 300){
// 處理結(jié)果 行 頭 空行 體
// 1.響應(yīng)行
console.log(xhr.status);//狀態(tài)碼
console.log(xhr.statusText);//狀態(tài)字符串
console.log(xhr.getAllResponseHeaders.toString());//所有響應(yīng)頭
console.log(xhr.response);//響應(yīng)體
result.innerHTML = xhr.response;
}else{
}
}
}
}
</script>設(shè)置參數(shù)
可以在url后面直接加上?參數(shù)名:值&參數(shù)名:值…
xhr.open('GET','//127.0.0.1:8082/server?name=admin&password=admin');
POST請求
<script>
const RESULT = document.getElementById("RESULT"); RESULT.addEventListener("mouseover",function(){
// 1. 創(chuàng)建對象
const xhr = new XMLHttpRequest();
// 2.初始化,設(shè)置請求類型 與 方法 xhr.open('POST','http://127.0.0.1:8082/server');
// 3. 發(fā)送請求
xhr.send();
// 4.事件處理
xhr.onreadystatechange=function(){
if(xhr.readyState === 4){
if(xhr.status >=200 && xhr.status<300){
RESULT.innerHTML=xhr.response;
// console.log(xhr.getAllResponseHeaders());
}
}
}
});
</script>報錯信息 Access to XMLHttpRequest at 'http://127.0.0.1:8082/server' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 已攔截跨源請求:同源策略禁止讀取位于 http://127.0.0.1:8082/server 的遠(yuǎn)程資源。(原因:CORS 頭缺少 'Access-Control-Allow-Origin')。狀態(tài)碼:404。 因為服務(wù)端沒有一個與之匹配的路由規(guī)則,而且沒有設(shè)置響應(yīng)頭
參數(shù)設(shè)置
// 在send方法里可以設(shè)置參數(shù),可以設(shè)置任意類型,任意格式的數(shù)據(jù)
xhr.send('a=100&b=200&c=300');1.6設(shè)置請求頭信息
// 設(shè)置請求頭信息 一般設(shè)置一些預(yù)定義的請求頭
// Content-Type 用來設(shè)置請求體的內(nèi)容類型
// application/x-www-form-urlencoded 設(shè)置參數(shù)查詢字符串的類型
// 請求頭信息也可以自定義,但是瀏覽器會有安全機(jī)制,
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 設(shè)置請求頭的信息是因為 要把身份校驗的信息放在頭信息里面,把他傳遞給服務(wù)器,由服務(wù)器對參數(shù)做提取,對用戶的身份進(jìn)行校驗
xhr.setRequestHeader('name','yxj');后端操作
// all表示可以接受所有類型的請求
app.all('/server',(request,response)=>{
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 響應(yīng)頭,允許所有的響應(yīng)頭類型
response.setHeader('Access-Control-Allow-Headers','*')
// 設(shè)置響應(yīng)體
response.send('Hello 原生AJAX POST!');
});2.1服務(wù)端響應(yīng)JSON數(shù)據(jù)
nodemon工具可以實時重啟服務(wù)器
<script>
const result = document.getElementById("result");
// 綁定鍵盤按下事件
window.onkeydown=function(){
// 1. 獲取xhr對象
const xhr = new XMLHttpRequest();
// 設(shè)置響應(yīng)體數(shù)據(jù)類型
xhr.responseType = 'json';
// 2.初始化
xhr.open('GET','http://127.0.0.1:8082/json-server');
// 3.發(fā)送
xhr.send();
// 4. 處理數(shù)據(jù)
xhr.onreadystatechange=function(){
if(xhr.readyState === 4){
if(xhr.status >=200 && xhr.status <300 ){
// 手動將數(shù)據(jù)轉(zhuǎn)換
// let data = JSON.parse(xhr.response);
// result.innerHTML= data.name;
// console.log(data);
// 自動轉(zhuǎn)換
console.log(xhr.response);
result.innerHTML= xhr.response.name;
}
}
}
}
</script>后臺
app.all('/json-server',(request,response)=>{
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 響應(yīng)頭,允許所有的響應(yīng)頭類型
response.setHeader('Access-Control-Allow-Headers','*')
// 設(shè)置一個響應(yīng)數(shù)據(jù)
const data={
name:"winter",
age:18,
sex:"man"
}
// 設(shè)置響應(yīng)體,send方法里只能接收字符串和Buffer 類型
//所以要對對象進(jìn)行一個轉(zhuǎn)換
let str = JSON.stringify(data);
response.send(str);
});2.2解決ie緩存問題
xhr.open('GET','http://127.0.0.1:8082/json-server?t='+Date.now());
//加一個時間戳,讓瀏覽器知道這是兩次不同的請求。2.3超時與網(wǎng)絡(luò)錯誤的處理
//超時設(shè)置 請求超過2s則取消請求
xhr.timeout = 2000;
// 超時回調(diào) 實際中應(yīng)該采取更加友好的方式
xhr.ontimeout = function(){
alert("網(wǎng)絡(luò)請求超時!");
}
// 網(wǎng)絡(luò)異?;卣{(diào)
xhr.onerror = function(){
alert("網(wǎng)絡(luò)異常!");
} xhr.open('GET','http://127.0.0.1:8082/out?'+Date.now());
xhr.send();2.4取消AJAX請求
const xhr = new XMLHttpRequest(); xhr.abort();
2.5Ajax重復(fù)發(fā)送請求情況
如果客戶端一直向服務(wù)器發(fā)送相同的請求,服務(wù)器的壓力就會很大,會接收到很多的相同請求。
解決辦法:
在向服務(wù)器發(fā)送請求之前先判斷之前有沒有發(fā)起過相同的請求,如果有就將之前的請求取消掉,重新發(fā)起請求。這樣一來我們向服務(wù)器發(fā)起的請求始終只有一個,服務(wù)器壓力就會小一些
<script>
const btn = document.getElementsByTagName("button")[0];
const result=document.getElementById("result");
let xhr = null;
//標(biāo)識變量
let isSending = false; //是否正在發(fā)送AJAX請求
btn.onclick=function(){
// 判斷標(biāo)識變量
if(isSending) xhr.abort();//如果正在發(fā)送,則取消該請求,創(chuàng)建一個新的請求
xhr = new XMLHttpRequest();
// 修改 標(biāo)識變量的值
isSending = true;
xhr.open('GET','http://127.0.0.1:8082/out?'+Date.now());
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
//修改標(biāo)識變量
isSending = false;
if(xhr.status >= 200 && xhr.status < 300){
result.innerHTML = xhr.response;
console.log(xhr.response);
}else{
}
}
}
}
</script>3.1JQuery發(fā)送AJAX請求
<script>
$('button').eq(0).click(function(){
//$.get/post方法接收的是參數(shù)
// 參數(shù)1:url 參數(shù)2:要發(fā)送的對象{} 參數(shù)三:回調(diào)函數(shù)(響應(yīng)體)操作服務(wù)器端返回的數(shù)據(jù) 參數(shù)4:設(shè)置響應(yīng)體類型
$.get('http://127.0.0.1:8082/getjquery',{a:100,b:200},function(data){
console.log(data);//對象
},'json')
});
$('button').eq(1).click(function(){
$.post('http://127.0.0.1:8082/postjquery',{a:300,b:400},function(data){
console.log(data);//沒+json會返回字符串
})
});
$('button').eq(2).click(function(){
//$.ajax方法接接收的是一個對象,對象里有響應(yīng)的屬性,通過屬性設(shè)置參數(shù)
$.ajax({
// url:
url:'http://127.0.0.1:8082/alljquery',
// 參數(shù),post請求才能設(shè)置請求體
data:{a:100,b:200},
// 類型
type:'POST',
// 響應(yīng)體結(jié)果
dataType:'json',
// 成功的回調(diào)
success:function(data){
console.log(data);
},
// 超時時間
timeout:8000,
// 失敗的回調(diào) 超時、網(wǎng)絡(luò)異常
error:function(){
console.log("出錯了");
},
// 頭信息設(shè)置
headers:{
name:'headers',
msg:'hiashfi',
}
});
});
</script>app.get('/getjquery',(request,response)=>{
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 設(shè)置響應(yīng)體
const data = {
name:'Jquery JSON',
type:'get JSON Type'
}
response.send(JSON.stringify(data));
});
// JQuery post
app.post('/postjquery',(request,response)=>{
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 響應(yīng)頭,允許所有的響應(yīng)頭類型
response.setHeader('Access-Control-Allow-Headers','*');
// 設(shè)置響應(yīng)體
const data = {
name:'Jquery JSON',
type:'POST JSON Type'
}
response.send(JSON.stringify(data));
});4.1 axios
Axios 是一個基于 promise 網(wǎng)絡(luò)請求庫,作用于node.js 和瀏覽器中。 在服務(wù)端它使用原生 node.js http 模塊, 而在客戶端 (瀏覽端) 則使用 XMLHttpRequests。
特性:
- 從瀏覽器創(chuàng)建 XMLHttpRequests
- 從 node.js 創(chuàng)建 http請求
- 支持 Promise API
- 攔截請求和響應(yīng)
- 轉(zhuǎn)換請求和響應(yīng)數(shù)據(jù)
- 取消請求
- 自動轉(zhuǎn)換JSON數(shù)據(jù)
- 客戶端支持防御XSRF
4.12發(fā)起一個get請求
// 向給定ID的用戶發(fā)起請求
axios.get('/user?ID=12345')
.then(function (response) {
// 處理成功情況
console.log(response);
})
.catch(function (error) {
// 處理錯誤情況
console.log(error);
})
.then(function () {
// 總是會執(zhí)行
});4.13 發(fā)起一個 POST 請求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});發(fā)起多個并發(fā)請求:
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
Promise.all([getUserAccount(), getUserPermissions()])
.then(function (results) {
const acct = results[0];
const perm = results[1];
});4.1.4 可以向 axios 傳遞相關(guān)配置來創(chuàng)建請求
// 發(fā)起一個post請求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});// 在 node.js 用GET請求獲取遠(yuǎn)程圖片
axios({
method: 'get',
url: 'http://bit.ly/2mTM3nY',
responseType: 'stream'
})
.then(function (response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});5.1使用fetch函數(shù)發(fā)送Ajax請求
fetch函數(shù)屬于全局對象,可以直接調(diào)用,返回的結(jié)果是promise對象
btns[0].onclick = function(){
// fetch(url,{})
fetch('http://127.0.0.1:8082/allaxios',{
// 請求方法
method:'POST',
// 請求頭
headers:{
name:'fetch'
},
// 請求體
body:'username=admin,password=123456'
}).then(response=>{
// console.log(response);
// return response.text();//轉(zhuǎn)成string
return response.json();//轉(zhuǎn)成json
}).then(response=>{
console.log(response);
})
}6.1同源策略
same-Oringin Policy最早由Netscape公司提出,是瀏覽器的一種安全策略
**同源:**協(xié)議、域名、端口號必須完全相同。
- 就是來自相同的一個服務(wù)
Ajax是默認(rèn)遵循同源策略的。不滿足同源策略是無法直接發(fā)送Ajax請求的。
例:
- 當(dāng)前網(wǎng)頁http://a.com 8000端口
- 目標(biāo)資源的協(xié)議也必須是http協(xié)議,a.com域名,8000端口
跨域原因:
- 因為單臺服務(wù)器,能力受限
- 加入更多的服務(wù)器提供更多的服務(wù)
6.2跨域的解決
6.2.1 JSONP
jsonp是什么?
- JSONP(JSON with Padding),是一個非官方的解決方案,純粹憑借程序員的聰明才智開發(fā)出來的,只支持get請求。
jsonp怎么工作?
- 在網(wǎng)頁有一些標(biāo)簽天生具有跨域能力,比如:img、link、iframe、script.
- jsonp利用script標(biāo)簽的跨域能力來發(fā)送請求的。
jsonp的使用
- 動態(tài)創(chuàng)建一個script標(biāo)簽
var script = document.createElement("script");- 設(shè)置script的src,設(shè)置回調(diào)函數(shù)
script.src = "http://localhost:3000/testAJAX?callback=abc";
7. CORS
// 設(shè)置響應(yīng)頭. 名字,* (設(shè)置所有協(xié)議、域名、端口、允許跨域)
response.setHeader('Access-Control-Allow-Origin','*');
// 指定端口允許跨域
response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8082');
// 響應(yīng)頭,允許所有的響應(yīng)頭類型
response.setHeader('Access-Control-Allow-Headers','*');
// 允許所有請求類型(get、post、...)
response.setHeader('Access-Control-Allow-Method','*');https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
CORS是什么?
CORS (Cross - Origin - Resource Sharing), 跨域資源共享。
CORS是官方的跨域解決方案,他的特點是愛不需要在客戶端做任何特殊的操作,完全在服務(wù)器中進(jìn)行處理,支持get和post請求。
跨域資源共享新增了一組HTTP首部字段,允許服務(wù)器聲明哪些源站通過瀏覽器有權(quán)限訪問哪些資源。
CORS是怎么工作的?
CORS通過設(shè)置一個響應(yīng)頭來告訴瀏覽器,該請求允許跨域,瀏覽器收到該響應(yīng)以后就會對響應(yīng)放行。
CORS的使用
主要是服務(wù)器里的設(shè)置:
router.get(“/testAJAX”,function(req,res){
})
btn.onclick = function(){
// 創(chuàng)建對象
var xhr = new XMLHttpRequest();
//
xhr.open('GET','http://127.0.0.1:8082/getcors');
//
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status<300){
console.log(xhr.response);
}
}
}
}到此這篇關(guān)于Ajax基礎(chǔ)使用詳解的文章就介紹到這了,更多相關(guān)Ajax基礎(chǔ)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ajax通過XML異步提交的方法實現(xiàn)從數(shù)據(jù)庫獲取省份和城市信息實現(xiàn)二級聯(lián)動(xml方法)
這篇文章主要介紹了Ajax通過XML異步提交的方法實現(xiàn)從數(shù)據(jù)庫獲取省份和城市信息實現(xiàn)二級聯(lián)動(xml方法)的相關(guān)資料,我們要根據(jù)異步提交,局部刷新的思想來實現(xiàn)來提高用戶交互問題,對ajax二級聯(lián)動效果感興趣的朋友一起看看吧2016-11-11
通過Ajax方式上傳文件使用FormData進(jìn)行Ajax請求
這篇文章主要介紹了通過Ajax方式上傳文件使用FormData進(jìn)行Ajax請求的相關(guān)資料,需要的朋友可以參考下2016-08-08
Ajax與mysql數(shù)據(jù)交互制作留言板功能(全)
這篇文章主要為大家詳細(xì)介紹了Ajax與mysql數(shù)據(jù)交互,實現(xiàn)留言板功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02
Ajax+php實現(xiàn)商品分類三級聯(lián)動
這篇文章主要介紹了Ajax+php實現(xiàn)商品分類三級聯(lián)動,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-08-08
AJAX+Servlet實現(xiàn)的數(shù)據(jù)處理顯示功能示例
這篇文章主要介紹了AJAX+Servlet實現(xiàn)的數(shù)據(jù)處理顯示功能,結(jié)合實例形式分析了前臺ajax與后臺Servlet生成隨機(jī)數(shù)顯示的相關(guān)交互操作技巧,需要的朋友可以參考下2018-06-06

