整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          web前端ajax筆記之一

          習大綱

          基礎(chǔ)學習路徑

          1.什么是AJAX

          1.1概念

          AJAX是Asynchronous javascript and xml 的縮寫,表示異步j(luò)avascript 和 xml ,是一種交互式網(wǎng)頁應(yīng)用開發(fā)技術(shù)。

          AJAX是一些老技術(shù)的新應(yīng)用, 應(yīng)用到了html css javascript dom , 以XMLHttpRequest為技術(shù)核心實現(xiàn)網(wǎng)頁異步數(shù)據(jù)傳輸。

          1.2特點

          最大特點就是:網(wǎng)頁不用刷新進行數(shù)據(jù)傳輸

          1.3應(yīng)用場景

          用戶注冊

          AJAX分頁效果

          圖片加載瀑布流效果

          2.AJAX工作流程

          傳統(tǒng)的數(shù)據(jù)提交方式

          AJAX數(shù)據(jù)提交方式

          通過上述對比,客戶端用戶部分減少了2個流程,交給了ajax去處理,那么就減少了用戶的等待時間,用戶體驗大大的提升

          3.AJAX的優(yōu)點

          ? 減少服務(wù)器帶寬,按需獲得數(shù)據(jù)

          注意:在一些有列表展示功能的地方優(yōu)勢特別突出

          ? 無刷新更新頁面,減少用戶的實際和心理等待時間

          注:用戶注冊,用戶登錄。多數(shù)據(jù)信息的展示

          ? 更好的用戶體驗,傳統(tǒng)數(shù)據(jù)提交會刷新頁面,易丟失用戶填寫數(shù)據(jù)

          ? 主瀏覽器都支持

          二、AJAX使用

          1.創(chuàng)建ajax對象

          XHR = new XMLHttpRequest();

          2.建立鏈接

          1.1語法

          創(chuàng)建請求頭使用OPEN,主要實現(xiàn)(請求類型,請求地址)

          對象.open(請求類型GET/POST,請求地址,[同步true/異步false]);

          默認:同步 True

          1.2代碼


          //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo.php');



          3.發(fā)送請求

          1.1語法

          主要實現(xiàn)請求服務(wù)器操作

          對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);

          1.2代碼


          【HTML代碼】
          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo.php');
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             XHRObj.send();
             
          </script>
          【PHP代碼】
          <?php
          echo 'test';


          腳下留心:

          一定要在服務(wù)器目錄下面運行AJAX-發(fā)送請求.html,不能直接用瀏覽器瀏覽該文件

          4.響應(yīng)請求(接受服務(wù)器返回的信息)

          1.1語法

          對象.responseText (獲取服務(wù)器響應(yīng)的字符串數(shù)據(jù))

          對象.responseXML(獲取服務(wù)器響應(yīng)的xml數(shù)據(jù))

          1.2代碼

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo.php');
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             
             XHRObj.send();
             //alert返回的數(shù)據(jù)
             alert(XHRObj.responseText);
             
          </script>

          案例運行結(jié)果

          腳下留心:無法響應(yīng)數(shù)據(jù)

          原因:在AJAX沒有完成請求這個時候是沒有返回值的,所以獲取數(shù)據(jù)是沒有結(jié)果的。

          解決方法:通過判斷reaystate == 4 是否AJAX請求完成

          1.3判斷服務(wù)器是否響應(yīng)成功

          Onreadystatechange 作用:ajax在請求的過程中發(fā)生任何狀態(tài)的變化都會調(diào)用該方法

          Readystate 作用:返回ajax的請求狀態(tài)

          狀態(tài)說明:

          最終代碼:以及結(jié)果

          思考:為什么沒有打印0~4

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo.php');
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             console.log(XHRObj.readyState);
             //發(fā)送請求
             XHRObj.send();
             //當請求狀態(tài)發(fā)送變化時ajax會自動調(diào)用該方法onreadystatechange
             XHRObj.onreadystatechange=function(){
                 console.log(XHRObj.readyState);
                 if(XHRObj.readyState==4){
                      console.log(XHRObj.responseText);
                 }
                 
             }
             console.log(XHRObj.readyState+'sdf');  
          </script>

          說明:

          程序是從上往下進行的, 里面的代碼是等發(fā)送異步請求完了才去執(zhí)行的。

          狀態(tài)0是無法獲取的,因為實例化AJAX的對象,然而監(jiān)聽需要對象對象里面的屬性來完成,所以0裝就是實例化對象的時候。

          思考:避免接口寫錯

          例如:

          在實際使用中,我們?yōu)榱酥挥性谡埱蟮慕涌谡_的時候獲取相應(yīng)的數(shù)據(jù),一般我們要判斷返回的HTTP狀態(tài)是否正確,

          使用:

          對象.status == 200

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo1.php');
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
          //    console.log(XHRObj.readyState);
             //發(fā)送請求
             XHRObj.send();
             //當請求狀態(tài)發(fā)送變化時ajax會自動調(diào)用該方法onreadystatechange
             XHRObj.onreadystatechange=function(){
          //        console.log(XHRObj.readyState);
                 if(XHRObj.readyState == 4 && XHRObj.status == 200){
                      console.log(XHRObj.responseText);
                 }
          //        else{
          //            //以郵件或者短信的形式發(fā)送通網(wǎng)站管理員
          //            alert('服務(wù)器錯誤,很忙......');
          //        }
                 
             }
             
          //    console.log(XHRObj.readyState+'sdf');
          </script>


          5.案例聯(lián)系-檢查用戶名是否存在

          1.1案例需求

          判斷用戶名admin是否存在,當存在的時候返回【不可用】,當不存在的時候返回【可用】

          1.2完成思路

          明確需求:

          第一步:給按鈕增加點擊事件

          第二步:獲取用戶輸入的值username

          第三步:使用AJAX將內(nèi)容發(fā)送給服務(wù)器端PHP文件

          第四步:編寫PHP文件checkuser.php 判斷用戶是否存在,返回結(jié)果

          第五步:將PHP返回的結(jié)果彈出來

          1.3HTML代碼

          <!--

          第一步:給按鈕增加點擊事件

          第二步:獲取用戶輸入的值username

          第三步:使用AJAX將內(nèi)容發(fā)送給服務(wù)器端PHP文件

          第四步:編寫PHP文件checkuser.php 接受參數(shù),并且判斷用戶是否存在,返回結(jié)果

          第五步:將PHP返回的結(jié)果彈出來

          -->


          <script type="text/javascript">
             //按鈕綁定事件,給input增加ID屬性
            var checkObj = document.getElementById('check');
            checkObj.onclick = function(){
                var username = document.getElementById('username').value;
                //創(chuàng)建ajax對象
                var XHRObj = new XMLHttpRequest();
                //創(chuàng)建請求頭,設(shè)置請求發(fā)送的地址和類型,并且將參數(shù)傳遞給服務(wù)端
                XHRObj.open('get','check.php?username='+username);
                //獲取服務(wù)器端返回的數(shù)據(jù)  
                XHRObj.onreadystatechange = function(){
                    if(XHRObj.readyState == 4 && XHRObj.status == 200){
                        alert(XHRObj.responseText);
                    }
                }
                //發(fā)送請求
                XHRObj.send();
               
            }
             
          </script>


          1.4PHP代碼


          <?php
          //定義一個用戶數(shù)組
          $user = array('admin','xiaoming','xiaohong','xiaoqiang');
          //獲取傳遞的參數(shù)
          $username = $_GET['username'];
          //判斷用戶是否存在在數(shù)組中
          if(in_array($username,$user)){
             echo '不可用';
          }else{
             echo '可用';
          }

          進化版本

          1)進化要求

          當用戶名可用的時候后面增加√說可用,當用戶名不可用的時候出現(xiàn)一個×提示當前用戶名太火,請換一個

          HTML代碼

          <style>
             .error{
                 color: red;
                 font-size: 14px;
             }
             .green{
                 color: green;
                 font-size: 14px;
             }
             
          </style>
          <body>
          <!--   <span class="error">×此用戶名太首歡迎,請換一個</span>-->
          <!--   <span class="green">√恭喜你,該用戶可用</span>-->
             <table border="1">
                 <th colspan="2">用戶注冊</th>
                 <tr>
                     <td><input id="username" name="username" type="text"/><div id='error'></div></td>
                     <td><input id="check" type="button" value="檢測用戶"/></td>
                 </tr>
                 
             </table>
          </body>
          <!--
          第一步:給按鈕增加點擊事件
          第二步:獲取用戶輸入的值username
          第三步:使用AJAX將內(nèi)容發(fā)送給服務(wù)器端PHP文件
          第四步:編寫PHP文件checkuser.php 接受參數(shù),并且判斷用戶是否存在,返回結(jié)果
          第五步:將PHP返回的結(jié)果彈出來
          -->
          <script type="text/javascript">
             //按鈕綁定事件,給input增加ID屬性
            var checkObj = document.getElementById('check');
            checkObj.onclick = function(){
                var username = document.getElementById('username').value;
                //創(chuàng)建ajax對象
                var XHRObj = new XMLHttpRequest();
                //創(chuàng)建請求頭,設(shè)置請求發(fā)送的地址和類型,并且將參數(shù)傳遞給服務(wù)端
                XHRObj.open('get','check.php?username='+username);
                //獲取服務(wù)器端返回的數(shù)據(jù)  
                XHRObj.onreadystatechange = function(){
                    if(XHRObj.readyState == 4 && XHRObj.status == 200){
          //               alert(XHRObj.responseText);
                        if(XHRObj.responseText =='可用'){
                             document.getElementById('error').innerHTML='<span class="green">√恭喜你,該用戶沒有被注冊</span>';
                        }else{
                            document.getElementById('error').innerHTML=' <span class="error">×此用戶名太首歡迎,請換一個</span>';
                           
                        }
                    }
                }
                //發(fā)送請求
                XHRObj.send();
               
            }
             
          </script>


          三、發(fā)送GET/POST請求

          1.POST和GET的區(qū)別

          數(shù)據(jù)方面:GET受瀏覽器的影響

          POST 原則上是不受限制的,可以通過PHP配置POST_MAX_SIZE進行更改

          安全方面:POST比GET要安全

          文件上傳:GET不能進行文件上傳

          2.Ajax之GET請求(加參數(shù))

          1.1實現(xiàn)方式

          說明:在請求地址后面增加參數(shù),例如:demo.php?a=111&b=222&c=333

          1.2代碼


          【HTML代碼】
          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭,請求方式,請求鏈接
             XHRObj.open('get','test.php?a=111&b=222&c=333');
             //發(fā)送請求
             XHRObj.send();
          </script>
          【PHP代碼】
          <?php
          var_dump($_GET);


          3.AJAX之POST請求

          1.1實現(xiàn)方式

          Open(‘POST’,請求地址);

          設(shè)置發(fā)送的數(shù)據(jù)格式,采用URL編碼格式

          對象.setRequestHeader(‘content-type’,’application/x-www-form-urlencoded’);

          對象.send(發(fā)送的數(shù)據(jù));

          1.2代碼

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             XHRObj.onreadystatechange = function() {
             if (XHRObj.readyState == 4) {
               alert(XHRObj.responseText);
             }
           }
             //創(chuàng)建請求頭,請求方式,請求鏈接
             XHRObj.open('post','test.php');
             //發(fā)送post的數(shù)據(jù)
             var postData = 'name=123123&age=rrr';
             
             //設(shè)置數(shù)據(jù)編碼格式,使用URL編碼格式
             XHRObj.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
             
             //發(fā)送請求
             XHRObj.send(postData);
          </script>


          【PHP代碼】

          <?php

          var_dump($_POST);

          效果

          4.練習:表單無刷新數(shù)據(jù)錄入

          四、AJAX同步異步請求

          1.概念

          同步:等待服務(wù)器響應(yīng)完成在執(zhí)行下一段JS代碼 (阻塞模式)

          異步:不等服務(wù)器響應(yīng)完成直接執(zhí)行下一段JS代碼(非阻塞模式)

          2.驗證同步

          設(shè)置open(方式,請求地址,false/同步);

          HTML【代碼】

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo.php',false);
             //時時監(jiān)控
             XHRObj.onreadystatechange = function(){
                 if(XHRObj.readyState == 4){
                     console.log('111');
                 }
             }
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             XHRObj.send();
             console.log('js執(zhí)行完成');
             
          </script>


          【PHP代碼】

          為了增加延遲效果使用sleep


          <?php
          sleep(8);
          echo 'test';


          3.驗證異步


          【HTML代碼】
          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','demo.php');
             //時時監(jiān)控
             XHRObj.onreadystatechange = function(){
                 if(XHRObj.readyState == 4){
                     console.log('111');
                 }
             }
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             XHRObj.send();
             console.log('js執(zhí)行完成');
             
          </script>

          【PHP代碼】


          <?php
          sleep(8);
          echo 'test';

          五、解決緩存問題

          1.緩存分析

          我們再瀏覽一些網(wǎng)站的時候瀏覽器為了方便用戶再次訪問的時候增加用戶訪問體驗會將一些靜態(tài)資源文件緩存到本地

          緩存的位置在:

          選中IE瀏覽器右鍵

          打開

          靜態(tài)緩存目錄就出現(xiàn)再這里面了

          說明:IE存在緩存

          2.解決方案

          1.1隨機數(shù)

          代碼設(shè)置:?t=Math.random()

          缺點:

          1.不能保證URL絕對唯一

          2.產(chǎn)生大量緩存文件

          1.2時間

          代碼設(shè)置:?t=new Date().getTime(); //取得毫秒時間戳

          優(yōu)點:保證URL絕對唯一

          缺點:依然產(chǎn)生大量緩存文件

          1.3設(shè)置請求頭

          代碼設(shè)置:對象.setRequestHeader("If-Modified-Since","0");

          原理分析:

          If-Modified-Since是標準的HTTP請求頭標簽,在發(fā)送HTTP請求時,把瀏覽器端緩存頁面的最后修改時間一起發(fā)到服務(wù)器去,服務(wù)器會把這個時間與服務(wù)器上實際文件的最后修改時間進行比較。

          如果時間一致,那么返回HTTP狀態(tài)碼304(不返回文件內(nèi)容),客戶端接到之后,就直接把本地緩存文件顯示到瀏覽器中。

          如果時間不一致,就返回HTTP狀態(tài)碼200和新的文件內(nèi)容,客戶端接到之后,會丟棄舊文件,把新文件緩存起來,并顯示到瀏覽器中。

          1.4設(shè)置相應(yīng)頭

          代碼設(shè)置:header("Cache-Control: no-cache, must-revalidate");

          原理分析:

          利用php的header函數(shù)向響應(yīng)頭中寫數(shù)據(jù),寫的是告訴客戶端:不要對本次的結(jié)果進行緩存。

          這種做法,可以從根本上解決緩存問題,不產(chǎn)生任何緩存文件。

          六、返回數(shù)據(jù)格式

          1.數(shù)據(jù)格式分類

          普通字符串文本格式:responseText

          XML數(shù)據(jù)格式:responseXML

          JSON 字符串數(shù)據(jù)格式:responseText (在實際工作中用到最多,最廣泛的格式)

          2.返回Text數(shù)據(jù)處理

          1.1HTML代碼

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','text.php');
             //時時監(jiān)控
             XHRObj.onreadystatechange = function(){
                 if(XHRObj.readyState == 4 && XHRObj.status == 200){
                     document.getElementById('content').innerHTML=XHRObj.responseText;
                 }
             }
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             XHRObj.send();
             
          </script>
          <body>
             <div id="content"></div>
          </body>

          1.2PHP代碼

          <?php

          echo '<h1>返回的文本</h1>';

          最終效果

          3.返回XML數(shù)據(jù)處理

          1.1HTML代碼

          <script type="text/javascript">
             //創(chuàng)建AJAX對象
             var XHRObj = new XMLHttpRequest();
             //創(chuàng)建請求頭
             XHRObj.open('GET','xml.php');
             //時時監(jiān)控
             XHRObj.onreadystatechange = function(){
                 if(XHRObj.readyState == 4 && XHRObj.status == 200){
                    var xmlObj = XHRObj.responseXML;
                     //以前獲取html文檔我們使用  document.getElementByTagName()
                     books = xmlObj.getElementsByTagName('book');
                     for(i=0;i<books.length;i++){
          //獲取第二級的值我們使用childen 方法
                         for(j=0;j<books[i].children.length;j++){
                             
                             console.log(books[i].children[j].innerHTML);
                         }
                     }
                 }
             }
             //發(fā)送請求  對象.send(POST請求則填寫POST的數(shù)據(jù)/GET請求可以不用寫);
             XHRObj.send();
             
             
          </script>

          1.2PHP代碼

          首先確保PHP寫的xml文件能再瀏覽器端訪問

          <?php
          header('Content-Type:text/xml; charset=utf-8');
          echo '<?xml version="1.0" encoding="utf-8"?>
          <books>
             <book>
                 <name>西游記</name>
                 <price>50.12</price>
             </book>
             
             <book>
                 <name>三國演義</name>
                 <price>876.12</price>
             </book>
             
          </books>
          ';

          4.返回JSON數(shù)據(jù)處理

          1.1什么是JSON數(shù)據(jù)

          JSON(javascript Object Notation js 對象標記) 是一種輕量級的數(shù)據(jù)交換格式。

          1.2JSON數(shù)據(jù)優(yōu)勢

          數(shù)據(jù)格式比較簡單,易于讀寫, 格式都是壓縮的,占用帶寬小

          易于解析這種語言,客戶端JavaScript可以簡單的通過eval()進行JSON數(shù)據(jù)的讀取

          因為JSON格式能夠直接為服務(wù)器端代碼使用, 大大簡化了服務(wù)器端和客戶端的代碼開發(fā)量, 但是完成的任務(wù)不變, 且易于維護

          1.3服務(wù)器端JSON生成和解析

          PHP端生成JSON數(shù)據(jù)使用:json_encode(數(shù)組數(shù)據(jù)格式);

          PHP端解析JSON數(shù)據(jù)使用:json_decode(待解碼數(shù)據(jù),true/false);

          說明:false 解碼出來的數(shù)據(jù)是一個對象,true,解碼出來的是一個數(shù)組

          1.4客戶端解析JSON數(shù)據(jù)

          由于我們返回值的處理使用的是responseText 格式

          ? JSON.parse()

          語法格式:JSON.parse(字符串);

          作用:從一個字符串中解析出json數(shù)據(jù)對象

          前提:字符串必須是json格式的字符串

          ? Eval


          七、綜合案例-用戶注冊

          1.需求

          用戶會員注冊功能,用戶填寫好根據(jù)規(guī)則進行驗證,如果驗證成功提示用戶注冊成功。

          驗證規(guī)則:

          1.用戶名不能為空

          2.用戶名必須是由數(shù)字和字母組成,而且是在6~8位之間

          2.HTML代碼


          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
          <head>
             <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
             <title>AJAX-用戶注冊</title>
          </head>
          <style>
             dd{float: left;}    
          </style>
          <body>
            <div>
                <dl>
                    <dd>用戶名</dd>
                    <dd><input type="text" name="username" id="username"></dd>
                    <dd><input type="button" id="regbtn"  value="注冊"></dd>
                </dl>
            </div>
             
          </body>
          <script type="text/javascript">
             
             //給注冊按鈕增加click事件
             
             var regbtn = document.getElementById('regbtn');
             
             regbtn.onclick = function(){
                 
                 //獲取用戶輸入的值
                 var username = document.getElementById('username').value;
                 
                  //創(chuàng)建AJAX對象
                 var XHRObj = new XMLHttpRequest();
                 //打開對象
                 XHRObj.open('get','reg.php?username='+username);
                 //實時監(jiān)控AJAX運行狀態(tài)
                 XHRObj.onreadystatechange = function(){
                     //判斷服務(wù)器是否響應(yīng)成功
                     if(XHRObj.readyState==4 && XHRObj.status == 200){
                         //將json數(shù)據(jù)轉(zhuǎn)換成對象
                         jsonObj = JSON.parse(XHRObj.responseText);
                         //判斷用戶是否操作成功進行頁面跳轉(zhuǎn)
                         if(jsonObj.state ==1){
                             location.href='success.html';
                             
                         }else{
                             alert(jsonObj.msg);
                         }
                     }
                 }
                 //發(fā)送請求
                 XHRObj.send();
                 
             }
             
           
             
             
          </script>
          </html>


          3.PHP代碼

          jax

          1 ajax的定義

          關(guān)于ajax的詳細介紹請讀者自行百度或者參考http://theodor.top/article/26中的“ajax”一節(jié)。

          簡單的來說,ajax請求返回的是一串組織好的數(shù)據(jù)。瀏覽器會在符合條件(js腳本)的情況下發(fā)送一系列符合條件的鏈接,來向服務(wù)器請求更新一組數(shù)據(jù)。服務(wù)器發(fā)送數(shù)據(jù)后,瀏覽器直接在當前頁面改寫DOM,達到不跳轉(zhuǎn)鏈接進行更新的目的。

          2 為什么要爬取ajax請求

          很多網(wǎng)站利用ajax對頁面進行美化處理,同時也能節(jié)省服務(wù)器的帶寬。

          有時候我們需要在資訊網(wǎng)站上爬取較多信息,而這些信息正常情況下需要用戶不斷在瀏覽器界面做出動作(大多數(shù)情況下這個動作是下拉滾動條)才能加載。如果使用selenium等無界面瀏覽器爬取則太耗時間,使用常規(guī)爬蟲庫則無法對爬取下來的html頁面做出動作(也就是激活js)。所以我們需要繞過動作,直接對ajax請求進行爬取,達到快速準確獲取數(shù)據(jù)的目的(事實上,ajax請求返回的數(shù)據(jù)一般都十分易讀,因為沒有html的干擾,但也不排除存在直接返回一段html的網(wǎng)站,比如百度貼吧)。

          通過ajax請求繞過瀏覽器操作

          本節(jié)我們以微博為例。

          1 獲取ajax鏈接

          我們可以用兩種方式獲取ajax鏈接:第一種是分析原頁面的script文件找到發(fā)送ajax請求的代碼;第二種是直接通過工具截取網(wǎng)頁發(fā)送的ajax請求url,分析其規(guī)律并仿寫。

          其中,分析script腳本是十分不推薦采取的方法,因為網(wǎng)站開發(fā)者通常會將js腳本寫成十分不友好的形式(請想象一堆var abcdefg出現(xiàn)在你面前,js甚至不用聲明變量類型)。但在窮途末路或者爬取者本身有興趣的情況下也不是不能一試。

          第二種方法中的工具可以用瀏覽器自帶的開發(fā)者工具(F12),當然想用Fiddler等也不是不可以,重要的是結(jié)果不是過程。在待爬取頁面按下F12鍵打開開發(fā)者工具,然后點擊標簽“Network”,將瀏覽的類別調(diào)整到“XHR”(XMLHTTPRequest,這是ajax專有的數(shù)據(jù)格式):

          不斷下拉滾動條,會發(fā)現(xiàn)XHR區(qū)域多了很多內(nèi)容。觀察可以得知它們是一系列GET請求,且其請求參數(shù)為ajwvr、category、page、lefnav、cursor、rnd。變動的參數(shù)為:page,其每次請求+1,推測為請求頁數(shù);rnd,可知其為請求發(fā)出的時間戳。

          2 解析ajax返回的json數(shù)據(jù)

          json全稱JavaScript Object Notation,是一種數(shù)據(jù)格式。大多數(shù)情況下,你可以將json數(shù)據(jù)看做字典。

          瀏覽器向服務(wù)器發(fā)送ajax請求后,服務(wù)器會返回一組json數(shù)據(jù),瀏覽器根據(jù)此json更新頁面。在繞過瀏覽器直接發(fā)送ajax請求時,服務(wù)器返回的json數(shù)據(jù)自然也由我們自行解析。

          在已經(jīng)拿到ajax請求的瀏覽器開發(fā)者工具下,雙擊ajax請求連接,在展開的窗口中選擇Response,可以看到微博服務(wù)器端返回的json數(shù)據(jù):

          其具體的json返回形式如下,其中data為其返回的html文本:

          {"code":"100000","msg":"","data":" <!--\u699c\u5355\u680f\u4f4d\u7f6e-->\n <div…(略)"}

          可知我們需要的數(shù)據(jù)在data鍵內(nèi),其為html文本段。

          實例:使用request爬取微博首頁的下拉滾動條更新內(nèi)容

          import requests
          
          import time 
          
          import datetime
          
          page=2 
          
          #分析得知ajax請求的page從2開始(因為page1在打開頁面的時候就已經(jīng)加載到文檔里)
          
          lefnav=0
          
          category=0
          
          ajwvr=6
          
          cursor=""
          
          #其余的參數(shù),其意義可以忽略
          
          url="https://weibo.com/a/aj/transform/loadingmoreunlogin?"
          
          #通過分析之前瀏覽器發(fā)出的ajax請求,可得知微博使用的時間戳為毫秒級時間戳
          
          def getrnd():
          
              return round(time.time()*1000)
          
          def geturl():
          
              global page #我們要修改page,就要聲明為全局變量
          
              page=page+1
          
              return url+"ajwvr="+str(ajwvr)+"&category="+str(category)+"&page"+str(page-1)+"&cursor="+cursor+"&_rnd="+str(getrnd())
          
          response=requests.get(geturl())
          
          print(response.text)

          當然,此處的ajax請求采取了GET的方式,但也有采取POST方式并且要求攜帶cookie的ajax請求。對于這種情況可以采用設(shè)置POST字典的方式。在真正的情況中也會有很多猜不出ajax請求參數(shù)的情況,這就需要讀者因地制宜隨機應(yīng)變了。但ajax請求的精髓已經(jīng)被我們講解過了,無論有多少分支,都不過萬變不離其宗耳。

          擴展

          是我的一家之見,若有疏漏還請一笑而過。

          其實除了ajax,網(wǎng)頁上幾乎所有的頁面都可以通過找到url->分析參數(shù)->偽裝請求的方式來爬取。比如說搜索框的操作可以通過向搜索框跳轉(zhuǎn)的鏈接發(fā)送請求來模擬,按鈕按下可以通過向按鈕綁定的鏈接發(fā)送請求來模擬。這是因為互聯(lián)網(wǎng)的本質(zhì)是數(shù)據(jù)與地址的組合,無論它們有多么華麗,終究也不過是一堆數(shù)據(jù)。發(fā)送請求的主動權(quán)在我們手上,只要分析手頭的數(shù)據(jù),可以說沒有什么請求是偽裝不了的(當然,我是指你本人使用瀏覽器可以做出的請求)。

          近項目上用到了調(diào)用微信和支付寶的第三方支付接口,因為以前沒用過,所以這次用到了之后總結(jié)一下分享給大家,這里介紹兩種支付方式,即app支付和掃碼支付方式。

          一、app支付(這里只介紹java端調(diào)用支付,安卓或ios端自己參考相關(guān)的調(diào)用文檔)

          首先可以看一看項目支付流程(圖解)

          1. 在頁面上選擇支付方式(微信或支付寶)

          2. 由相應(yīng)的客戶端調(diào)用相應(yīng)的支付方式進入相應(yīng)的支付頁面(安卓或ios調(diào)用支付接口并進入微信或支付寶支付頁面,顯示支付的信息)

          3. 輸入密碼進行支付

          4. 調(diào)用支付結(jié)果接口,來返回支付成功與否

          四圖分別是選擇支付方式、微信支付頁面、支付寶支付頁面、微信支付結(jié)果(成功)頁面

          也是基本的支付三個步驟。

          一、先看微信支付:

          在調(diào)用微信支付之前你應(yīng)該已經(jīng)下單成功(即訂單信息入庫成功),這里需要幾個值:

          OrderName(訂單名稱),orderNumber(訂單編號,唯一),amount(金額), prepayId(交易會話id)

          前三個參數(shù)直接從數(shù)據(jù)庫里獲取。prepayid是什么?可以具體看微信支付文檔,我們可以從下單接口中返回獲得這個會話id并且需要入庫,這個參數(shù)最重要的作用是用于第一次我們沒有支付,但已經(jīng)生成了一個待支付的訂單。這種情況下我們不需要再次去調(diào)用下單接口返回prepayId,因為我們已經(jīng)生成過了這個值

          下面看手機端頁面的js代碼:


          1. //微信支付
          2. function wxPay(outTradeNo){
          3. var orderType="0"; //路線 訂單
          4. $.ajax({
          5. url :'<%=basePath%>client/travel/getWXClientPayInfo.do?outTradeNo='+outTradeNo+'&orderType='+orderType,
          6. cache : false,
          7. type : "get",
          8. success : function(data)
          9. {
          10. if(data!=null){
          11. data = jQuery.parseJSON(data);
          12. var u = navigator.userAgent;
          13. var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
          14. var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
          15. if(isAndroid){
          16. ClientInterface.pay(outTradeNo,data.prepayid,data.noncestr,data.timestamp,data.sign,orderType);
          17. }

          主站蜘蛛池模板: 亚洲日本一区二区| 国产一区二区三区美女| 亚洲av无码一区二区三区观看| 成人免费视频一区| 一本大道东京热无码一区| 婷婷国产成人精品一区二| 久久人妻无码一区二区 | 无码人妻aⅴ一区二区三区| 国模大尺度视频一区二区| 国产精品区一区二区三| 四虎在线观看一区二区| 国产短视频精品一区二区三区| 无码欧精品亚洲日韩一区| 国产精品免费一区二区三区四区| 国产精品 一区 在线| 一区二区在线视频观看| 日本强伦姧人妻一区二区| 国产伦精品一区二区三区免.费| 精产国品一区二区三产区| 色综合视频一区中文字幕| 亚洲乱色熟女一区二区三区蜜臀| 精品福利视频一区二区三区| 97久久精品一区二区三区| 精品性影院一区二区三区内射| 久久亚洲一区二区| 日韩中文字幕精品免费一区| 亚洲熟女乱色一区二区三区| 亚洲欧洲专线一区| 国产在线观看一区二区三区四区| 国产一区二区三区在线电影| 亚洲日韩国产一区二区三区| 国产一区二区三区在线观看精品| 农村人乱弄一区二区 | 中文字幕日韩丝袜一区| 自拍日韩亚洲一区在线| 精品国产精品久久一区免费式| 精品女同一区二区三区免费播放 | 亚洲AV无码一区二区三区DV| 亚洲美女视频一区二区三区| 在线观看精品视频一区二区三区| 日本免费精品一区二区三区|