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 的事件