Django之Ajax提交
Django之Ajax提交
Ajax:提交数据,页面不刷新。Ajax要引入jQuery。
Ajax 是基于异步JavaScript和XML创建的交互式页面应用技术。
JS实现页面的跳转:
location.href = "/url/"
1 $ajax({ 2 url:'要提交的地址', 3 type:"POST", #GET 或 POST 的提交方式 4 data:{"k1":"v1","k2":"v2"}, #提交的数据 5 success:function(data){ 6 #当前服务端处理完毕后,字典执行的回调函数 7 #data返回的数据 8 console.log(data); 9 if (data=='ok'): 10 location.href = "/url/" 11 else: 12 return HttpR...... 13 } 14 })
原生Ajax:
原生Ajax 是用了一个浏览器的一个对象,这个对象是XMLHttpRequest。
前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>首页</h1> <input type="text" id="i1" /> + <input type="text" id="i2" /> = <input type="text" id="i3" /> <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();" /> <input type="button" id="btn2" value="原生Ajax" onclick="add2();" /> <script src="/static/jquery-1.12.4.js"></script> <script> function add1(){ $.ajax({ url: '/add1/', type: 'POST', data: {'i1': $('#i1').val(),'i2': $('#i2').val()}, success:function(arg){ $('#i3').val(arg); } }) } function add2(){ /* GET请求 var xhr = new XMLHttpRequest(); //新创建的对象,只有创建了对象,才有open等方法。 xhr.onreadystatechange = function(){ //onreadystatechange是回调函数,只要状态发生变化,这个函数就会被执行 if(xhr.readyState == 4){ //定义等readyState的值为4时,在执行这个回调函数。 alert(xhr.responseText); //responseText是服务端返回的内容 } }; xhr.open('GET','/add2/?i1=12&i2=19'); //open里指定打开的方式。 xhr.send(); //send 发送数据 */ #POST请求 var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ alert(xhr.responseText); } }; xhr.open('POST','/add2/'); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send("i1=12&i2=19"); } </script> </body> </html>
后端代码:
from django.shortcuts import render,HttpResponse def index(request): return render(request,'index.html') def add1(request): a1 = int(request.POST.get('i1')) a2 = int(request.POST.get('i2')) return HttpResponse(a1 + a2) def add2(request): if request.method == "GET": i1 = int(request.GET.get('i1')) i2 = int(request.GET.get('i2')) print('add2.....') return HttpResponse(i1+i2) else: print(request.POST) print(request.body) #body里是请求体数据 return HttpResponse('...')
在原生ajax中,用GET请求发送数据是不用设置请求头的,但是在POST中,是要加上
setRequestHeader('Content-Type','application/x-www-form-urlencoded') 的。
伪Ajax:伪Ajax是不用XMLHttpRequest,他是用浏览器的特性,用标签和标签的特性来伪造的。
在伪ajax中,就要说到iframe标签。
在iframe标签中的src中定义的任何网址,都会完全将这个网址搬运过来。
iframe 具有不刷新打开页面的功能。
比如在我们的index页面中,访问我们的index,在页面标签中用iframe,src设置成百度的url,
那么当我们访问index时,页面内容就是百度的内容。
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div> <input type="text" id="txt1" /> //input里输入的url,提交给onclick,onclick事件交给iframe去提交。 <input type="button" value="查看" onclick="changeScr();"/> </div> <iframe id="ifr" style="width: 1000px;height: 2000px;" src="http://www.baidu.com.cn"></iframe> <script> function changeScr(){ var inp = document.getElementById('txt1').value; document.getElementById('ifr').src = inp; } </script> </body> </html>
后端:
def baidu(request): return render(request,'baidu.html')
用form提交ifr,也可以做到页面不刷新:
form是把数据打包发送,但页面刷新,可以form中加入iframe,也会使其页面不刷新并提交数据。
后端:
def fake_ajax(request): if request.method == "GET": return render(request,'fake_ajax.html') else: print(request.POST) return HttpResponse('返回值')
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> //target是将原有的form提交方式交给ifr去提交。 <iframe id="ifr" name="ifr" style="display: none"></iframe> //用iframe提交form的数据,style为none是将整个标签隐藏起来。iframe里面放的是页面的返回值。 //iframe里面在有返回值时,会执行一个onload,表示加载了返回的数据。 <input type="text" name="user" /> <a onclick="submitForm();">提交</a> //通过a标签提交onload </form> <script> function submitForm(){ document.getElementById('ifr').onload = loadIframe; document.getElementById('f1').submit(); //通过js提交form表单 } function loadIframe(){ var content = document.getElementById('ifr').contentWindow.document.body.innerText; //通过回调的方式,取iframe的内容。 alert(content); } </script> </body> </html>
跨域Ajax:用JSONP。
json是字符串,而jsonp是一个小技巧。
用到jsonp是因为在ajax中,存在一些问题:
ajax中的问题:
ajax访问自己的域名url是没有问题的,但是如果ajax访问其他域名的url,ajax是报错的。
其报错原因是浏览器的同源策略。
一个正常的请求经过ajax提交,并拿到返回数据返回,但是如果ajax提交的数据的url是其他的url,那么前端是拿不到的。浏览器是阻止访问的。
在这个流程中,客户的请求是发送到了服务器,并且服务器也返回了数据,只不过是浏览器给禁止的这个操作。
浏览器的同源策略:
在ajax跨域发送请求,并带有返回值返回时,浏览器是拒绝接受的。
而jsonp就是弥补这个小缺陷的。
jsonp是可以绕过浏览器的同源策略并拿到数据的。
浏览器阻止的是ajax的操作,但是并不能阻止scr属性的操作,比如script标签。
远程发请求,是要告诉对方我们的url是什么的。
所以jsonp就是这么做的。
示例:向其他网站发Http请求,
后端:
def jsonp(request): return render(request,'jsonp.html')
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <script src="/static/commons.js"></script> </head> <body> <a onclick="sendMsg();">发送</a> <script> function sendMsg(){ var tag = document.createElement('script'); //发送端,把数据拼接成script,然后把script放在html中,给他创建一个对象,加在页面就可以发送这个请求啦 tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403"; //这个url就是要跨域的。可以换成任何url。 document.head.appendChild(tag); } </script> </body> </html>
static的内容:commons.js
function list(arg){
console.log(arg);
}
API:
API就是一个url,我们总说API是个接口,其实本质就是一个url,这个url带有数据发送给来的请求。
S5的url向s4的url发送请求,并拿到s4的用户列表,
流程是点击s5的发送按钮,发送ajax请求,发送到s4的url,拿到s4的用户列表,并显示在s5的页面中。
实例:
我们定义一个服务端,叫s4,用来接收请求,并返回请求数据:
服务端的S4的的view。
import json from django.shortcuts import render,HttpResponse from django.core.handlers.wsgi import WSGIRequest from django.views import View def users(request): v = request.GET.get('funcname') #获取一个动态的变量名v print('请求来了...')
#这个user_list就是s4要返回给s5的列表数据 user_list = [ 'alex','eric','egon' ] user_list_str = json.dumps(user_list) temp = "%s(%s)" %(v,user_list_str,) #将v的变量名赋予user_list的值,使其变量不会被当做是全局变量使用。 print(temp) return HttpResponse(temp) def new_users(request): print(request.method) if request.method == "OPTIONS": obj = HttpResponse() obj['Access-Control-Allow-Origin'] = "*" obj['Access-Control-Allow-Methods'] = "DELETE" return obj obj = HttpResponse('asdfasdf') obj['Access-Control-Allow-Origin'] = "*" return obj # user_list = [ # 'alex','eric','egon' # ] # user_list_str = json.dumps(user_list) # obj = HttpResponse(user_list_str) # # obj['Access-Control-Allow-Origin'] = "*" # return obj
我们在S5的发送请求中,去访问S4,也既是一个跨域操作,用到了Jsonp的特性。
s5的view
def jsonp(request): # import requests # requests.get() # requests.post() return render(request,'jsonp.html') def cors(request): return render(request,'cors.html')
S5的template 的前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" value="获取用户列表" onclick="getUsers();" /> <ul id="user_list"> </ul> <script src="/static/jquery-1.12.4.js"></script> <script> /* function getUsers(){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ var content = xhr.responseText; console.log(content); } }; xhr.open('GET','http://www.s4.com:8001/users/'); xhr.send(); } */ //a = ['alex','eric','egon'] /* function getUsers(){ var tag = document.createElement('script'); tag.src = "http://www.s4.com:8001/users/?funcname=bbb?sdd"; document.head.appendChild(tag); } function bbb(arg){ console.log(arg); } */ function getUsers(){ // XMLHttpRequest /* $.ajax({ url: 'http://www.s4.com:8001/users/?funcname=bbb', type: 'GET', success:function(arg){ console.log(arg); } }) */ // JSONP $.ajax({ url: 'http://www.s4.com:8001/users/', type: 'POST', dataType: 'JSONP', jsonp: 'funcname', jsonpCallback: 'bbb' }) } function bbb(arg){ console.log(arg); } </script> </body> </html>
JSONP只能发GET请求。
参考:articles/5703697.html
------- END ------