1. Jquery 對象能夠經過 .index() 進行取出自當前元素在父級元素中存放的索引;javascript
2. 瀏覽器的同源策略 -- Ajax 在訪問非本網站的時候,在數據返回的時候,會被瀏覽器攔截html
- 後端使用 requests 獲取數據後,發送給前端前端
- jsonp 在前端頁面中, 帶有 src 屬性的標籤不受同源策略的影響(img, script, iframe等),咱們能夠經過使用 script 標籤來獲取內容,但 script 中 src 獲取內容後,得到到的字符串(相似於調用python中的 eval 或 exec)會被 JS 執行,因此咱們能夠定義一個函數,而後讓服務端返回的內容外面包裹一層這個函數名,前端在訪問的時候把這個函數名發送過去,並提早定義好該函數
java
服務端返回的數據python
def server(request): return HttpResponse("aaa('important data!!!')")
客戶端定義及獲取數據jquery
<!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>Client</title> <script src="/static/jquery-3.2.1.js"></script> <script> $(function(){ }); var url = 'http://127.0.0.1:8000/server.html/'; // 服務端路徑 var $script; // 模擬使用建立的標籤名 function aaa(data){ // 數據返回後用來接收的函數 alert(data); document.head.removeChild($script); // 接收完數據後,從頁面刪除剛纔使用的標籤 } function getInfo(){ $script = document.createElement("script"); // 建立一個 script 標籤 $script.setAttribute("src", url); // 將須要請求數據的地址放入 script 的 src 中 document.head.appendChild($script); // 將標籤放入到 head 中 } </script> </head> <body> <h1>Client</h1> <input type="button" onclick="getInfo()" value="getInfo"> </body> </html>
服務端返回的數據web
from django.shortcuts import render from django.http import HttpResponse, JsonResponse def server(request): # 根據後端發送過來的名字來決定返回時,數據外面套的內容 funcName = request.GET.get("callback") return HttpResponse("%s('important data!!!')"%funcName)
客戶端定義及獲取數據ajax
<!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>Client</title> <script src="/static/jquery-3.2.1.js"></script> <script> function bbb(data){ alert(data); } $(function(){ var url = 'http://127.0.0.1:8000/server.html/'; // 服務端路徑 $.ajax({ url: url, // 跨站請求數據的路徑 type: 'GET', // 發送方式爲 get, 因爲使用的是 script, 因此只支持 get dataType: 'JSONP', // 使用 JSONP 方式 jsonp: 'callback', // get 發送的時候,後面跟的數據名爲 callback jsonpCallback: 'bbb' // get 發送數據的callback的值爲 bbb }) }); </script> </head> <body> <h1>Client</h1> <input type="button" value="getInfo"> </body> </html>
隨着技術的發展,如今的瀏覽器能夠支持主動設置從而容許跨域請求,即:跨域資源共享(CORS,Cross-Origin Resource Sharing),其本質是設置響應頭,使得瀏覽器容許跨域請求。django
cors 分爲簡單請求和非簡單請求,簡單請求只發送一次,直接發送數據,非簡單請求則會發送兩次數據,第一次發送 opption 請求(預檢),爲的是查看真正的數據是否能夠被接收(數據頭和請求方式是否符合要求), 若是符合要求,服務端能夠把內容加入到頭文件中來告訴瀏覽器;json
條件: 一、請求方式:HEAD、GET、POST 二、請求頭信息: Accept Accept-Language Content-Language Last-Event-ID Content-Type 對應的值是如下三個中的任意一個 application/x-www-form-urlencoded multipart/form-data text/plain 注意:同時知足以上兩個條件時,則是簡單請求,不然爲複雜請求
- 請求方式:OPTIONS - 「預檢」其實作檢查,檢查若是經過則容許傳輸數據,檢查不經過則再也不發送真正想要發送的消息 - 如何「預檢」 => 若是複雜請求是PUT等請求,則服務端須要設置容許某請求,不然「預檢」不經過 Access-Control-Request-Method => 若是複雜請求設置了請求頭,則服務端須要設置容許某請求頭,不然「預檢」不經過 Access-Control-Request-Headers
簡單請求:在使用cors的時候,客戶端幾乎不用修改,只須要按照普通的ajax的請求方式發送,在服務端返回數據的時候,只要在返回的時候,加上一個響應頭就能夠解決這個問題了
def example(request): response = HttpResponse("返回的數據內容") response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8888" # 容許訪問獲取信息的域名 return response
服務器設置響應頭:Access-Control-Allow-Origin = '域名' 或 '*',容許訪問獲取信息的域名,若是後面是*的話,表明容許全部的請求,若是須要每個相應都設置該響應頭的話(即這個網站的全部資源均可以被其它域名的所訪問,那麼咱們能夠在中間件中設置這個響應頭);
對於複雜請求,會先發一次預檢(OPTIONS)請求,若是服務端容許,那麼再發送一次正式請求(如PUT等,總之就是正真的請求),這個時候,咱們須要在後端進行判斷,若是容許用戶獲取數據,那麼當預檢(OPTIONS)過來的時候,咱們須要返回容許訪問的請求:Access-Control-Allow-Methds
if request.method == "OPTIONS": response = HttpResponse() // 返回的內容能夠爲空,主要須要返回請求頭 response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Methods'] = 'PUT' # 容許的複雜請求方式爲 PUT 請求;若是多個,用逗號分隔, "PUT, DELETE" response['Access-Control-Allow-Headers'] = "k1" # 複雜請求還有一種狀況就是定製請求頭,這種狀況下,咱們在返回的相應中應該設置該響應頭,表明容許發送請求頭的key是什麼,若是多個,逗號分隔 "k1, k2" return response
若是咱們不想每次都通過「預檢」這個環節的話,那麼咱們能夠在服務器的響應頭中增長一組:Access-Control-Max-Age的響應頭,能夠寫成
response['Access-Control-Allow-Headers'] = 10 # 默認單位爲秒
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="x-ua-compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>Title</title> 8 <script src="/static/jquery-3.2.1.js"></script> 9 <script> 10 $(function(){ 11 $("#btn01").click(function(){ 12 $.ajax({ 13 url: "http://127.0.0.1:8000/btn01/", 14 success: function(data){ 15 console.log(data) 16 } 17 }) 18 }); 19 20 $("#btn02").click(function(){ 21 $.ajax({ 22 url: "http://127.0.0.1:8000/btn02/", 23 type: "PUT", 24 success: function(data){ 25 console.log(data) 26 } 27 }) 28 }); 29 30 $("#btn03").click(function(){ 31 $.ajax({ 32 url: "http://127.0.0.1:8000/btn03/", 33 headers: {"k1": "asdfasdf"}, 34 success: function(data){ 35 console.log(data) 36 } 37 }) 38 }) 39 }) 40 </script> 41 </head> 42 <body> 43 <p><input type="button" value="簡單請求" id="btn01"></p> 44 <p><input type="button" value="複雜請求-PUT" id="btn02"></p> 45 <p><input type="button" value="複雜請求-Headers" id="btn03"></p> 46 </body> 47 </html>
1 from django.shortcuts import render 2 from django.http import HttpResponse 3 4 # Create your views here. 5 def btn01(request): 6 response = HttpResponse("btn01") 7 response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8888" 8 return response 9 10 11 def btn02(request): 12 if request.method == "OPTIONS": 13 response = HttpResponse() 14 response['Access-Control-Allow-Origin'] = '*' 15 response['Access-Control-Allow-Methods'] = 'PUT' 16 return response 17 18 if request.method == "PUT": 19 response = HttpResponse("btn02") 20 response['Access-Control-Allow-Origin'] = '*' 21 return response 22 23 24 def btn03(request): 25 if request.method == "OPTIONS": 26 response = HttpResponse() 27 response['Access-Control-Allow-Origin'] = '*' 28 response['Access-Control-Allow-Headers'] = "k1" 29 return response 30 31 if request.method == "GET": 32 response = HttpResponse("btn03") 33 response['Access-Control-Allow-Origin'] = '*' 34 return response
攜帶cookie的傳輸
若是在使用Ajax請求的時候,須要傳遞cookie的時候,咱們則須要在發送ajax的時候,以及服務器給咱們相應的時候加上一組頭信息
客戶端須要加:XMLHttpRequest的withCredentials爲true
$.ajax({ url: "http://c2.com:8000/test/", type: 'PUT', dataType: 'text', headers: {'k1': 'v1'}, xhrFields:{withCredentials: true}, // 加在了這裏 success: function(data, statusText, xmlHttpRequest){ console.log(data); } })
服務端須要加:Access-Control-Allow-Credentials爲true
class MainHandler(tornado.web.RequestHandler): def put(self): self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.set_header('Access-Control-Allow-Credentials', "true") # 加在了這裏 self.set_header('xxoo', "seven") self.set_header('bili', "daobidao") self.set_header('Access-Control-Expose-Headers', "xxoo,bili") self.set_cookie('kkkkk', 'vvvvv'); self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs): self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.set_header('Access-Control-Allow-Headers', "k1,k2") self.set_header('Access-Control-Allow-Methods', "PUT,DELETE") self.set_header('Access-Control-Max-Age', 10)
http://www.cnblogs.com/wupeiqi/articles/5703697.html
3. 模擬點擊事件
$("#a").trigger("chick"); // 模擬執行 id=a 的事件