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