整合營銷服務(wù)商

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

          免費咨詢熱線:

          XML HttpRequest 最佳實踐詳解

          ML HttpRequest(XHR) 技術(shù)是構(gòu)建動態(tài)、響應(yīng)式網(wǎng)站的關(guān)鍵。這項技術(shù)使得網(wǎng)頁能在不重新加載整個頁面的情況下與服務(wù)器進(jìn)行數(shù)據(jù)交互,極大地優(yōu)化了用戶的交互體驗。

          • XML HttpRequest 是什么?詳細(xì)講解其用法

          定義 XML HttpRequest

          XML HttpRequest 是一種瀏覽器與服務(wù)器進(jìn)行數(shù)據(jù)交換的 API。盡管它的名字包含 “XML”,XHR 實際上支持多種數(shù)據(jù)格式,如 JSON、HTML 和純文本等。初期,它主要用于處理 XML 格式數(shù)據(jù),但隨著時間的發(fā)展,XHR 的功能已經(jīng)大為擴展。

          • 什么是 JSON?JSON 文件是干什么的

          工作流程分析

          使用 XML HttpRequest 的基本步驟包括:

          1. 初始化對象:創(chuàng)建一個新的 XML HttpRequest 對象實例。
          2. 配置請求:通過調(diào)用 .open() 方法設(shè)置請求方法(例如 GET 或 POST)和目標(biāo) URL。
          3. 執(zhí)行發(fā)送:利用 .send() 方法發(fā)起請求,該方法中可以包含需要發(fā)送的數(shù)據(jù)。
          4. 監(jiān)聽并處理返回:通過事件監(jiān)聽器處理來自服務(wù)器的響應(yīng)。

          實際運用一例

          以下 JavaScript 代碼演示了如何通過 XML HttpRequest 發(fā)起一個 GET 請求:

          // 初始化一個XML HttpRequest對象
          var xhr = new XML HttpRequest();
          
          // 設(shè)置請求的方法和URL
          xhr.open('GET', 'https://api.example.com/data', true);
          
          // 定義響應(yīng)的處理邏輯
          xhr.onreadystatechange = function() {
              if (xhr.readyState === 4 && xhr.status === 200) {
                  console.log(xhr.responseText); // 輸出響應(yīng)數(shù)據(jù)
              }
          };
          
          // 執(zhí)行請求
          xhr.send();
          

          在此示例中,我們配置了請求和如何在接收到響應(yīng)后處理數(shù)據(jù)。

          主要使用場景

          動態(tài)內(nèi)容加載

          XML HttpRequest 允訟網(wǎng)頁動態(tài)地加載和顯示數(shù)據(jù),而無需刷新頁面,提高了網(wǎng)站的整體性能和用戶體驗。

          異步表單提交

          使用 XHR,表單數(shù)據(jù)可以異步提交,從而避免頁面刷新,用戶可以無縫繼續(xù)他們的網(wǎng)站活動。

          實時數(shù)據(jù)交互

          對于需要頻繁更新數(shù)據(jù)的應(yīng)用,如實時報表或聊天應(yīng)用,XHR 提供了持續(xù)與服務(wù)器通信的能力。

          優(yōu)點與挑戰(zhàn)

          優(yōu)勢

          • 用戶體驗提升:異步通信意味著更快的響應(yīng)時間和無干擾的用戶界面。
          • 效率高:只傳輸必需的數(shù)據(jù),減輕了服務(wù)器負(fù)擔(dān)。
          • 高度兼容性:支持多種數(shù)據(jù)格式和跨平臺使用。

          挑戰(zhàn)

          • 代碼復(fù)雜度:管理異步邏輯,需處理多種可能的執(zhí)行路徑和錯誤。
          • 安全考量:需警惕 XSS 等安全漏洞。
          • 對舊版本IE的支持:較老IE版本中實現(xiàn) XHR 的方式有所不同。

          現(xiàn)代 Web 開發(fā)的替代技術(shù)

          • 如何在 React 中使用 Fetch API

          雖然 Fetch API 在現(xiàn)代 Web 開發(fā)中逐漸成為新的標(biāo)準(zhǔn),提供了更簡潔的 API 和更好的錯誤處理機制,F(xiàn)etch 的使用示例如下:

          fetch('https://api.example.com/data')
              .then(response => response.json())
              .then(data => console.log(data))
              .catch(error => console.error('Error:', error));
          

          Fetch 基于 Promises,簡化了處理異步操作的復(fù)杭性。

          總結(jié)

          XML HttpRequest 是 Web 開發(fā)者必須掌握的重要工具之一。盡管有更現(xiàn)代的技術(shù)如 Fetch API,了解 XHR 仍對處理舊項目或理解 Web 開發(fā)的歷史背景非常有用。無論是更新現(xiàn)有的網(wǎng)站還是開發(fā)新的應(yīng)用,XHR 都是一個寶貴的資源。

          eact定義的一種類似于XML的JS擴展語法,用來簡化創(chuàng)建虛擬DOM

          <!DOCTYPE html>
          <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <meta name="viewport" content="width=device-width, initial-scale=1.0">
                  <title>jsx</title>
                  <style>
                      .title{
                          background-color: orange:
                          width: 200px;
                      }
                  </style><!--定義個樣式,也可以寫在CSS文件里,引入進(jìn)來-->
              </head>
          
              <body>
                  <div id="test"></div>
                  <script type="text/javascript" src="../js/react.development.js"></script>
                  <script type="text/javascript" src="../js/react-dom.development.js"></script>
                  <script type="text/javascript" src="../js/babel.min.js"></script>
              </body>
              <script type="text/babel">
                  const myid= "lOVE you"
                  const mydata= "hellO jsx"
                  const VDOM = ( // <!--h2標(biāo)簽引入樣式,用className,span標(biāo)簽引入內(nèi)聯(lián)樣式的時候,不是用雙引號,而是雙花括號,-->
                  <div>
                      <h2 className="title" id={myid.toLowerCase()}> 
                          <span style={{color:'red',fontSize:'29px'}}>{mydata.toLowerCase()}</span>
                      </h2>)// <!--標(biāo)簽中混入JS表達(dá)式時要用花括號{},如這里mydata取值 -->
                      //jsx中只能有一個根標(biāo)簽,比如這里的h2,可以在h2的外面包一層div,就可以寫兩個h2
                      <h2 className="title" id={myid.toUpperCase()}> 
                          <span style={{color:'red',fontSize:'29px'}}>{mydata.toLowerCase()}</span>
                      </h2>)
                      //標(biāo)簽首字母若是小寫字母,則將該標(biāo)簽轉(zhuǎn)為html中同名元素,若html中無該標(biāo)簽對應(yīng)的同名元素,則報錯
                      //標(biāo)簽首字母若是大寫字母,react就去渲染對應(yīng)的組件,若組件沒有定義,則報錯
                  </div>
          
                  ReactDOM.render(VDOM,document.getElementById('test'))
              </script>
          </html>
          

          一個jsx的小練習(xí)

           <script type="text/babel">
                  const data=['A','B','C']
                  const VDOM = (
                      <div>   //js表達(dá)式會產(chǎn)生一個值。js語句(代碼),有if,for,switch判斷,
                          <h1>jsx框架</h1>
                          <ul>
                            {
                              data.map((item,index)=>{
                                  return <li key={index}>{item}</li>
                              }) //item拿到data里面對應(yīng)的值,map遍歷的第二個值是索引值,
                            }
                          </ul>
                      </div>
                  )
                  ReactDOM.render(VDOM,document.getElementById('test'))
              </script>

          對應(yīng)的網(wǎng)頁如下:

          模塊是向外提供特定功能的js程序,一般就是一個js文件。

          組件比模塊更高一級,比如實現(xiàn)一個網(wǎng)頁的頭部的html,字體,css,js,圖像這些元素組合在一起,就形成了頭部這個組件。

          組件分為函數(shù)式組件和類式組件:

          函數(shù)式組件:

          <script type="text/babel">
          function MyComponent(){
          return <h2>show the function component</h2>
          }
          ReactDOM.render(<MyComponent/>,document.getElementById('test'))
          //<MyComponent/>要寫上標(biāo)簽,函數(shù)定義首字母需要大寫
          </script>

          執(zhí)行了ReactDOM.render(<MyComponent/>。。之后,React解析組件標(biāo)簽,找到MyComponent組件,發(fā)現(xiàn)組件是使用函數(shù)定義的,隨后調(diào)用該函數(shù),將返回的虛擬DOM轉(zhuǎn)為真是DOM,隨后呈現(xiàn)在頁面中。

          類式組件:

          上一篇文章中:Python如何解析HTML和XML數(shù)據(jù),我們介紹如何使用Python解析HTML和XML數(shù)據(jù),其中提到xpath的使用。事實上,xpath的功能非常強大,熟練使用可以給數(shù)據(jù)提取帶來極大的方便,所以今天打算做進(jìn)一步的介紹。

          準(zhǔn)備

          本文依然使用lxml進(jìn)行html/xml數(shù)據(jù)解析,可以自行使用pip進(jìn)行安裝,如不熟悉pip的使用,可以參考另一篇文章:如何管理python軟件包。

          先使用urllib2去抓取一個HTML頁面,比如前篇提到的中航電子2017年一季度交易記錄:

          >>> import urllib2

          >>> url = 'http://quotes.money.163.com/trade/lsjysj_600372.html?year=2017&season=1'

          >>> rsp = urllib2.urlopen(url).read()

          使用lxml.html軟件包進(jìn)行解析:

          >>> from lxml import html

          >>> doc = html.document_fromstring(rsp)

          >>> doc.tag

          'html'

          可以看到,當(dāng)前doc代表的是html元素。

          什么是XPath

          XPath,是XML Path Language的縮寫,是一種用于從XML文檔中選取節(jié)點的查詢語言,也可以用于對節(jié)點內(nèi)容進(jìn)行計算。xpath的標(biāo)準(zhǔn)是由W3C制定的。xpath雖然經(jīng)歷了多個版本(1999-v1.0, 2007-v2.0, 2014-v3.0, 2017-v3.1),但v1.0的使用仍然最廣泛,其官方文檔可以參考:

          https://www.w3.org/TR/xpath/

          XPath表達(dá)式

          在xpath看來,XML文檔就是一顆由節(jié)點構(gòu)成的樹,其中節(jié)點可以分為元素節(jié)點(element node)、屬性節(jié)點(attribute node)和文本節(jié)點(text node)。xpath最基本的語法結(jié)構(gòu)是表達(dá)式(expression),表達(dá)式運行之后可以返回一下四類結(jié)果:

          • 一組節(jié)點(不重復(fù))

          • 布爾取值true/false

          • 數(shù)值(浮點類型)

          • 字符串

          分別看下面例子:

          >>> doc.xpath('child::*')

          [<Element head at 0x10f478ec0>, <Element body at 0x10f478ba8>]

          >>> doc.xpath('3 < 2')

          False

          >>> doc.xpath('3 = 3')

          True

          >>> doc.xpath('3 + 2')

          5.0

          >>> doc.xpath('2 * 3')

          6.0

          >>> doc.xpath('6 div 3')

          2.0

          >>> doc.xpath('3 mod 2')

          1.0

          >>> doc.xpath('/html/head/meta[@name="robots"]/@name')

          ['robots']

          路徑與步

          XPath最重要的一類表達(dá)式,是用于節(jié)點選取的路徑(Location Path),看一個例子:

          >>> doc.xpath('/html/head/meta[@name="robots"]')

          [<Element meta at 0x10f478ba8>]

          可以看到,一條路徑有若干步(step)組成,步之間使用斜杠"/"分隔,每一步都從上下文節(jié)點中選取滿足條件的若干節(jié)點。路徑可分為相對路徑和絕對路徑類,比如:

          >>> doc.xpath('/html/head/meta[@name="robots"]') #絕對路徑,從根節(jié)點開始

          [<Element meta at 0x10f478ba8>]

          >>> doc.xpath('head/meta[@name="robots"]') #相對路徑,從當(dāng)前節(jié)點開始

          [<Element meta at 0x10f478ba8>]

          如果想同時查詢多條路徑,可以使用或“|”操作符:

          >>> doc.xpath('/html/head | /html/body')

          [<Element head at 0x10f478c58>, <Element body at 0x10f478c00>]

          軸(axis)

          上面的路徑采用的都是縮寫的形式,其實它還有完全形式的寫法,比如:

          >>> doc.xpath('/child::html/child::head/child::meta[@name="robots"]')

          [<Element meta at 0x10f478ba8>]

          在該寫法中,以child::meta[@name="robots"]為例,這一步是什么意思呢?對該步而言,上下文節(jié)點是head,該步的意思是從head的meta類型的子節(jié)點中選取name屬性取值為robots的節(jié)點,其中child是axis的名字,meta是要選擇的節(jié)點類型,@name="robots"是要滿足的條件。事實上,每一步都由這三部分構(gòu)成的,它們的作用:

          • 一個軸(axis):指明該步要選取的節(jié)點跟當(dāng)前節(jié)點的關(guān)系,例如上面的child說明要選取當(dāng)前節(jié)點的子節(jié)點

          • 一個節(jié)點測試(node test):指明這個路徑步要選取的節(jié)點類型,比如上面child::meta要選取的是meta類型的節(jié)點

          • 零個或多個謂詞(predicates)組成:起過濾作用、選取特定節(jié)點,比如上面[@name="robots"]要篩選屬性值為robots的節(jié)點

          除了child axis, xpath還定義了很多其他的axis,請看下表:

          看下面一些例子:

          1) 獲取子節(jié)點:getchildren()等價于child::*

          >>> doc.xpath('child::*')

          [<Element head at 0x10e8bad60>, <Element body at 0x10e8e5d60>]

          >>> doc.getchildren()

          [<Element head at 0x10e8bad60>, <Element body at 0x10e8e5d60>]

          2) 獲取當(dāng)前節(jié)點:"."等價于 self::node()

          >>> doc.xpath(".")

          [<Element html at 0x10dc1d4c8>]

          >>> doc.xpath("self::node()")

          [<Element html at 0x10dc1d4c8>]

          3) 獲取父節(jié)點:".."等價于parent::node()

          >>> doc.head.xpath("..")

          [<Element html at 0x10dc1d4c8>]

          >>> doc.head.xpath("parent::node()")

          [<Element html at 0x10dc1d4c8>]

          4)ancestor軸和descendant軸

          分別代表當(dāng)前元素所有祖先元素、所有后代元素,比如:

          >>> meta.xpath('ancestor::*')

          [<Element html at 0x10dc1d4c8>, <Element head at 0x10e8bad60>]

          >>> meta.xpath('ancestor::head')

          [<Element head at 0x10e8bad60>]

          >>> doc.xpath('descendant::table')

          >>> doc.xpath('descendant::table[@id="tcdatafields"]')

          >>> doc.xpath('//table[@id="tcdatafields"]')

          5)ancestor-or-self 和 descendant-or-self軸

          分別表示當(dāng)前元素或其所有祖先元素、當(dāng)前元素或其所有后代元素,比如:

          >>> meta.xpath('ancestor-or-self::*')

          [<Element html at 0x10dc1d4c8>, <Element head at 0x10e8bad60>, <Element meta at 0x10e8bae68>]

          6)child和parent軸

          分別表示當(dāng)前元素所有子元素、父元素:

          >>> doc.xpath('child::*')

          [<Element head at 0x10e8bad60>, <Element body at 0x10e8baf18>]

          >>> doc.xpath('child::head')

          [<Element head at 0x10e8bad60>]

          >>> head.xpath('child::meta[1]')

          [<Element meta at 0x10e8baf18>]

          >>> head.xpath('child::meta[position()<3]')

          [<Element meta at 0x10e8baf18>, <Element meta at 0x10e8bad08>]

          7)attribute軸

          表示當(dāng)前元素的所有屬性,例如下面是meta元素的name和content兩個屬性以及取值:

          >>> meta.items()

          [('name', 'googlebot'), ('content', 'index, follow')]

          獲取所有屬性取值:

          >>> meta.xpath('attribute::*')

          ['googlebot', 'index, follow']

          獲取name屬性的取值:

          >>> meta.xpath('attribute::name')

          ['googlebot']

          8)following和preceding

          分別表示當(dāng)前元素的所有后繼元素、前置元素,比如:

          >>> meta.xpath('following::*')

          >>> meta.xpath('preceding::*')

          9)following-sibling和preceding-sibling軸

          分別表示當(dāng)前元素的所有平級后繼元素、平級前置元素,比如:

          >>> meta.xpath('preceding-sibling::*')

          >>> meta.xpath('following-sibling::*')

          10)self軸

          表示當(dāng)前元素自身

          >>> doc.xpath("self::*")

          [<Element html at 0x10dc1d4c8>]

          使用謂詞(predicates)

          謂詞就是step中使用中括號[...]定義的那部分,使用謂詞能實現(xiàn)精確查找,看下面的例子:

          >>> doc.xpath('/html/head/meta')

          [<Element meta at 0x10e8baf70>, <Element meta at 0x10e8bae10>, <Element meta at 0x10e8bacb0>, <Element meta at 0x10e8baf18>, <Element meta at 0x10e8bad08>, <Element meta at 0x10e8bafc8>, <Element meta at 0x10e8bae68>]

          1) 位置謂詞

          >>> doc.xpath('/html/head/meta[1]')

          [<Element meta at 0x10e8baf70>]

          >>> doc.xpath('/html/head/meta[2]')

          [<Element meta at 0x10e8bae10>]

          >>> doc.xpath('/html/head/meta[last()]')

          [<Element meta at 0x10e8bae68>]

          >>> doc.xpath('/html/head/meta[last()-1]')

          [<Element meta at 0x10e8bae10>]

          >>> doc.xpath('/html/head/meta[position()<3]')

          [<Element meta at 0x10e8baf70>, <Element meta at 0x10e8bae10>]

          注:這里使用了last()和position()兩個函數(shù),xpath還支持更多的函數(shù),結(jié)合這些函數(shù)可以獲得非常強大的處理能力。

          2) 屬性謂詞

          含有屬性name的meta元素:

          >>> doc.xpath('/html/head/meta[@name]')

          [<Element meta at 0x10e8bacb0>, <Element meta at 0x10e8baf70>, <Element meta at 0x10e8bae10>, <Element meta at 0x10e8bae68>]

          含有屬性name而且其取值為robots的meta元素:

          >>> doc.xpath('/html/head/meta[@name="robots"]')

          [<Element meta at 0x10e8bacb0>]

          含有任意屬性的meta元素:

          >>> doc.xpath('/html/head/meta[@*]')

          3) 函數(shù)謂詞

          xpath內(nèi)置很多函數(shù),靈活使用這些函數(shù),可以極大提升查找效率,比如:

          -使用 text()函數(shù)

          >>> doc.xpath('//td[text()="2017-03-21"]')

          [<Element td at 0x10e8bacb0>]

          - 使用contains函數(shù)

          >>> [ td.text for td in doc.xpath('//td[contains(text(), "2017-03-2")]')]

          ['2017-03-29', '2017-03-28', '2017-03-27', '2017-03-24', '2017-03-23', '2017-03-22', '2017-03-21', '2017-03-20']

          - 使用starts-with函數(shù)

          >>> [ td.text for td in doc.xpath('//td[starts-with(text(),"2017-02-2")]')]

          ['2017-02-28', '2017-02-27', '2017-02-24', '2017-02-23', '2017-02-22', '2017-02-21', '2017-02-20']

          >>> [ td.text for td in doc.xpath('//td[text()>21.0 and text()<23.0]')]

          ['21.02']

          >>> [ td.text for td in doc.xpath('//td[text()< -2.5 or text()>21.0]')]

          ['21.02', '-2.64']

          通配符

          xpath也支持通配符"*",其中'*"可以匹配任何標(biāo)簽元素,"@*"可以匹配任何元素屬性,node()可以匹配任何節(jié)點:

          >>> head.xpath('./*')

          [<Element title at 0x10e8baf18>, <Element meta at 0x10e8bacb0>, <Element meta at 0x10e8baf70>, <Element meta at 0x10e8bad08>, <Element meta at 0x10e8bafc8>, <Element meta at 0x10e8bae10>, <Element meta at 0x10e8c6050>, <Element meta at 0x10e8bae68>, <Element link at 0x10e8c60a8>, <Element link at 0x10e8c6100>]

          >>> head.xpath('./meta[@*]')

          [<Element meta at 0x10e8baf18>, <Element meta at 0x10e8bacb0>, <Element meta at 0x10e8baf70>, <Element meta at 0x10e8bad08>, <Element meta at 0x10e8bafc8>, <Element meta at 0x10e8bae10>, <Element meta at 0x10e8bae68>]

          >>> head.xpath('./node()')

          ['\r\n', <Element title at 0x10e8badb8>, '\r\n', <Element meta at 0x10e8baf18>, '\r\n', <Element meta at 0x10e8bacb0>, '\r\n', <Element meta at 0x10e8baf70>, '\r\n', <Element meta at 0x10e8bad08>, '\r\n', <Element meta at 0x10e8bafc8>, '\r\n', <Element meta at 0x10e8bae10>, '\r\n', <Element meta at 0x10e8bae68>, '\r\n', <Element link at 0x10e8c6050>, '\n', <Element link at 0x10e8c60a8>, '\r\n']

          今天就寫這么多。


          主站蜘蛛池模板: 国产成人无码AV一区二区在线观看| 亚洲爆乳精品无码一区二区| 亚洲av成人一区二区三区观看在线 | 中文字幕一区视频| 久久精品一区二区免费看| 在线播放偷拍一区精品| 天美传媒一区二区三区| 国产成人一区在线不卡| 久久久久人妻精品一区| 中文字幕无码一区二区免费| 久久精品一区二区三区日韩| 精品无码一区二区三区在线| 午夜在线视频一区二区三区 | 无码国产精品一区二区免费模式| 免费无码一区二区三区| 国产精品亚洲一区二区三区久久| 一区二区福利视频| 久久综合精品国产一区二区三区| 亚洲色无码一区二区三区 | 亚洲色精品aⅴ一区区三区 | 国产成人精品一区二三区| 国产一区二区三区精品久久呦| 久久精品一区二区三区资源网 | 久久国产午夜一区二区福利| 欧美人妻一区黄a片| 中文字幕一区二区人妻性色 | 亚洲一区二区观看播放| 一区二区三区四区精品| 中文字幕在线一区二区在线 | 国产精品伦子一区二区三区| 日韩精品无码一区二区三区免费| 午夜AV内射一区二区三区红桃视| 国产高清在线精品一区小说| 亚洲熟女综合色一区二区三区| 亚洲一区二区三区无码中文字幕| 怡红院美国分院一区二区| 国99精品无码一区二区三区 | 国产成人一区二区精品非洲| 亚洲国产老鸭窝一区二区三区| 日韩精品一区在线| 美女免费视频一区二区|