日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

第12讲:Ajax 的原理和解析

發(fā)布時(shí)間:2024/4/11 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第12讲:Ajax 的原理和解析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

當(dāng)我們?cè)谟?requests 抓取頁(yè)面的時(shí)候,得到的結(jié)果可能會(huì)和在瀏覽器中看到的不一樣:在瀏覽器中正常顯示的頁(yè)面數(shù)據(jù),使用 requests 卻沒(méi)有得到結(jié)果。這是因?yàn)?requests 獲取的都是原始 HTML 文檔,而瀏覽器中的頁(yè)面則是經(jīng)過(guò) JavaScript 數(shù)據(jù)處理后生成的結(jié)果。這些數(shù)據(jù)的來(lái)源有多種,可能是通過(guò) Ajax 加載的,可能是包含在 HTML 文檔中的,也可能是經(jīng)過(guò) JavaScript 和特定算法計(jì)算后生成的。

對(duì)于第 1 種情況,數(shù)據(jù)加載是一種異步加載方式,原始頁(yè)面不會(huì)包含某些數(shù)據(jù),只有在加載完后,才會(huì)向服務(wù)器請(qǐng)求某個(gè)接口獲取數(shù)據(jù),然后數(shù)據(jù)才被處理從而呈現(xiàn)到網(wǎng)頁(yè)上,這個(gè)過(guò)程實(shí)際上就是向服務(wù)器接口發(fā)送了一個(gè) Ajax 請(qǐng)求。

按照 Web 的發(fā)展趨勢(shì)來(lái)看,這種形式的頁(yè)面將會(huì)越來(lái)越多。網(wǎng)頁(yè)的原始 HTML 文檔不會(huì)包含任何數(shù)據(jù),數(shù)據(jù)都是通過(guò) Ajax 統(tǒng)一加載后再呈現(xiàn)出來(lái)的,這樣在 Web 開(kāi)發(fā)上可以做到前后端分離,并且降低服務(wù)器直接渲染頁(yè)面帶來(lái)的壓力。

所以如果你遇到這樣的頁(yè)面,直接利用 requests 等庫(kù)來(lái)抓取原始頁(yè)面,是無(wú)法獲取有效數(shù)據(jù)的。這時(shí)我們需要分析網(wǎng)頁(yè)后臺(tái)向接口發(fā)送的 Ajax 請(qǐng)求,如果可以用 requests 來(lái)模擬 Ajax 請(qǐng)求,就可以成功抓取了。

所以,本課時(shí)我們就來(lái)了解什么是 Ajax 以及如何去分析和抓取 Ajax 請(qǐng)求。

什么是 Ajax

Ajax,全稱為 Asynchronous JavaScript and XML,即異步的 JavaScript 和 XML。它不是一門(mén)編程語(yǔ)言,而是利用 JavaScript 在保證頁(yè)面不被刷新、頁(yè)面鏈接不改變的情況下與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁(yè)的技術(shù)。

傳統(tǒng)的網(wǎng)頁(yè),如果你想更新其內(nèi)容,那么必須要刷新整個(gè)頁(yè)面。有了 Ajax,便可以在頁(yè)面不被全部刷新的情況下更新其內(nèi)容。在這個(gè)過(guò)程中,頁(yè)面實(shí)際上在后臺(tái)與服務(wù)器進(jìn)行了數(shù)據(jù)交互,獲取到數(shù)據(jù)之后,再利用 JavaScript 改變網(wǎng)頁(yè),這樣網(wǎng)頁(yè)內(nèi)容就會(huì)更新了。

你可以到 W3School 上體驗(yàn)幾個(gè) Demo 來(lái)感受一下:http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_send.asp。

實(shí)例引入

瀏覽網(wǎng)頁(yè)的時(shí)候,我們會(huì)發(fā)現(xiàn)很多網(wǎng)頁(yè)都有下滑查看更多的選項(xiàng)。以我微博的主頁(yè)為例:https://m.weibo.cn/u/2830678474。我們切換到微博頁(yè)面,發(fā)現(xiàn)下滑幾個(gè)微博后,后面的內(nèi)容不會(huì)直接顯示,而是會(huì)出現(xiàn)一個(gè)加載動(dòng)畫(huà),加載完成后下方才會(huì)繼續(xù)出現(xiàn)新的微博內(nèi)容,這個(gè)過(guò)程其實(shí)就是 Ajax 加載的過(guò)程,如圖所示:


我們注意到頁(yè)面其實(shí)并沒(méi)有整個(gè)刷新,這意味著頁(yè)面的鏈接沒(méi)有變化,但是網(wǎng)頁(yè)中卻多了新內(nèi)容,也就是后面刷出來(lái)的新微博。這就是通過(guò) Ajax 獲取新數(shù)據(jù)并呈現(xiàn)的過(guò)程。

基本原理

初步了解了 Ajax 之后,我們?cè)賮?lái)詳細(xì)了解它的基本原理。發(fā)送 Ajax 請(qǐng)求到網(wǎng)頁(yè)更新的過(guò)程可以簡(jiǎn)單分為以下 3 步:

  • 發(fā)送請(qǐng)求
  • 解析內(nèi)容
  • 渲染網(wǎng)頁(yè)

下面我們分別詳細(xì)介紹一下這幾個(gè)過(guò)程。

發(fā)送請(qǐng)求

我們知道 JavaScript 可以實(shí)現(xiàn)頁(yè)面的各種交互功能,Ajax 也不例外,它是由 JavaScript 實(shí)現(xiàn)的,實(shí)際上執(zhí)行了如下代碼:

var xmlhttp; if (window.XMLHttpRequest) {//code for IE7+, Firefox, Chrome, Opera, Safarixmlhttp=new XMLHttpRequest();} else {//code for IE6, IE5xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() {if (xmlhttp.readyState==4 && xmlhttp.status==200) {document.getElementById("myDiv").innerHTML=xmlhttp.responseText;} } xmlhttp.open("POST","/ajax/",true); xmlhttp.send();

這是 JavaScript 對(duì) Ajax 最底層的實(shí)現(xiàn),這個(gè)過(guò)程實(shí)際上是新建了 XMLHttpRequest 對(duì)象,然后調(diào)用 onreadystatechange 屬性設(shè)置監(jiān)聽(tīng),最后調(diào)用 open() 和 send() 方法向某個(gè)鏈接(也就是服務(wù)器)發(fā)送請(qǐng)求。

前面我們用 Python 實(shí)現(xiàn)請(qǐng)求發(fā)送之后,可以得到響應(yīng)結(jié)果,但這里請(qǐng)求的發(fā)送由 JavaScript 來(lái)完成。由于設(shè)置了監(jiān)聽(tīng),所以當(dāng)服務(wù)器返回響應(yīng)時(shí),onreadystatechange 對(duì)應(yīng)的方法便會(huì)被觸發(fā),我們?cè)谶@個(gè)方法里面解析響應(yīng)內(nèi)容即可。

解析內(nèi)容

得到響應(yīng)之后,onreadystatechange 屬性對(duì)應(yīng)的方法會(huì)被觸發(fā),此時(shí)利用 xmlhttp 的 responseText 屬性便可取到響應(yīng)內(nèi)容。這類似于 Python 中利用 requests 向服務(wù)器發(fā)起請(qǐng)求,然后得到響應(yīng)的過(guò)程。

返回的內(nèi)容可能是 HTML,也可能是 JSON,接下來(lái)我們只需要在方法中用 JavaScript 進(jìn)一步處理即可。比如,如果返回的內(nèi)容是 JSON 的話,我們便可以對(duì)它進(jìn)行解析和轉(zhuǎn)化。

渲染網(wǎng)頁(yè)

JavaScript 有改變網(wǎng)頁(yè)內(nèi)容的能力,解析完響應(yīng)內(nèi)容之后,就可以調(diào)用 JavaScript 針對(duì)解析完的內(nèi)容對(duì)網(wǎng)頁(yè)進(jìn)行下一步處理。比如,通過(guò) document.getElementById().innerHTML 這樣的操作,對(duì)某個(gè)元素內(nèi)的源代碼進(jìn)行更改,這樣網(wǎng)頁(yè)顯示的內(nèi)容就改變了,這種對(duì) Document 網(wǎng)頁(yè)文檔進(jìn)行如更改、刪除等操作也被稱作 DOM 操作。

上例中,document.getElementById(“myDiv”).innerHTML=xmlhttp.responseText這個(gè)操作便將 ID 為 myDiv 的節(jié)點(diǎn)內(nèi)部的 HTML 代碼更改為服務(wù)器返回的內(nèi)容,這樣 myDiv 元素內(nèi)部便會(huì)呈現(xiàn)出服務(wù)器返回的新數(shù)據(jù),網(wǎng)頁(yè)的部分內(nèi)容看上去就更新了。

可以看到,發(fā)送請(qǐng)求、解析內(nèi)容和渲染網(wǎng)頁(yè)這 3 個(gè)步驟其實(shí)都是由 JavaScript 完成的。

Ajax 分析

這里還是以前面的微博為例,我們知道拖動(dòng)刷新的內(nèi)容由 Ajax 加載,而且頁(yè)面的 URL 沒(méi)有變化,這時(shí)我們應(yīng)該到哪里去查看這些 Ajax 請(qǐng)求呢?

這里還需要借助瀏覽器的開(kāi)發(fā)者工具,下面以 Chrome 瀏覽器為例來(lái)介紹。

首先,用 Chrome 瀏覽器打開(kāi)微博鏈接 https://m.weibo.cn/u/2830678474,隨后在頁(yè)面中點(diǎn)擊鼠標(biāo)右鍵,從彈出的快捷菜單中選擇“檢查” 選項(xiàng),此時(shí)便會(huì)彈出開(kāi)發(fā)者工具,如圖所示:

前面也提到過(guò),這里就是頁(yè)面加載過(guò)程中瀏覽器與服務(wù)器之間發(fā)送請(qǐng)求和接收響應(yīng)的所有記錄。

Ajax 有其特殊的請(qǐng)求類型,它叫作 xhr。在圖中我們可以發(fā)現(xiàn)一個(gè)以 getIndex 開(kāi)頭的請(qǐng)求,其 Type 為 xhr,這就是一個(gè) Ajax 請(qǐng)求。用鼠標(biāo)點(diǎn)擊這個(gè)請(qǐng)求,可以查看這個(gè)請(qǐng)求的詳細(xì)信息。

在右側(cè)可以觀察到 Request Headers、URL 和 Response Headers 等信息。Request Headers 中有一個(gè)信息為 X-Requested-With:XMLHttpRequest,這就標(biāo)記了此請(qǐng)求是 Ajax 請(qǐng)求,如圖所示:

隨后我們點(diǎn)擊 Preview,即可看到響應(yīng)的內(nèi)容,它是 JSON 格式的。這里 Chrome 為我們自動(dòng)做了解析,點(diǎn)擊箭頭即可展開(kāi)和收起相應(yīng)內(nèi)容。

我們可以觀察到,返回結(jié)果是我的個(gè)人信息,包括昵稱、簡(jiǎn)介、頭像等,這也是用來(lái)渲染個(gè)人主頁(yè)所使用的數(shù)據(jù)。JavaScript 接收到這些數(shù)據(jù)之后,再執(zhí)行相應(yīng)的渲染方法,整個(gè)頁(yè)面就渲染出來(lái)了。

另外,我們也可以切換到 Response 選項(xiàng)卡,從中觀察到真實(shí)的返回?cái)?shù)據(jù),如圖所示:

接下來(lái),切回到第一個(gè)請(qǐng)求,觀察一下它的 Response 是什么,如圖所示:

這就是最原始鏈接 https://m.weibo.cn/u/2830678474 返回的結(jié)果,其代碼只有不到 50 行,結(jié)構(gòu)也非常簡(jiǎn)單,只是執(zhí)行了一些 JavaScript。

所以說(shuō),我們看到的微博頁(yè)面的真實(shí)數(shù)據(jù)并不是最原始的頁(yè)面返回的,而是在執(zhí)行 JavaScript 后再次向后臺(tái)發(fā)送 Ajax 請(qǐng)求,瀏覽器拿到數(shù)據(jù)后進(jìn)一步渲染出來(lái)的。

過(guò)濾請(qǐng)求

接下來(lái),我們?cè)倮?Chrome 開(kāi)發(fā)者工具的篩選功能篩選出所有的 Ajax 請(qǐng)求。在請(qǐng)求的上方有一層篩選欄,直接點(diǎn)擊 XHR,此時(shí)在下方顯示的所有請(qǐng)求便都是 Ajax 請(qǐng)求了,如圖所示:

接下來(lái),不斷滑動(dòng)頁(yè)面,可以看到頁(yè)面底部有一條條新的微博被刷出,而開(kāi)發(fā)者工具下方也不斷地出現(xiàn) Ajax 請(qǐng)求,這樣我們就可以捕獲到所有的 Ajax 請(qǐng)求了。

隨意點(diǎn)開(kāi)一個(gè)條目,都可以清楚地看到其 Request URL、Request Headers、Response Headers、Response Body 等內(nèi)容,此時(shí)想要模擬請(qǐng)求和提取就非常簡(jiǎn)單了。

下圖所示的內(nèi)容便是我某一頁(yè)微博的列表信息:

到現(xiàn)在為止,我們已經(jīng)可以分析出 Ajax 請(qǐng)求的一些詳細(xì)信息了,接下來(lái)只需要用程序模擬這些 Ajax 請(qǐng)求,就可以輕松提取我們所需要的信息了。

總結(jié)

以上是生活随笔為你收集整理的第12讲:Ajax 的原理和解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。