django上课笔记7
Posted _慕
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django上课笔记7相关的知识,希望对你有一定的参考价值。
一、jQuery Ajax 和 原生Ajax
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘, views.index), url(r‘^add1/‘, views.add1), url(r‘^add2/‘, views.add2), ]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>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() { // jQuery Ajax $.ajax({ url:‘/add1/‘, type:‘POST‘, data:{‘i1‘:$(‘#i1‘).val(),‘i2‘:$(‘#i2‘).val()}, success:function (arg) { $(‘#i3‘).val(arg) } }) } function add2() { /* // 原生 Ajax 的 GET 方式 var xhr = new XMLHttpRequest(); // 创建对象XMLHttpRequest xhr.onreadystatechange = function () { // onreadystatechange方法是监控当有返回值时,自动执行回调函数 if (xhr.readyState == 4){ // Number readyState 状态值(整数) // 详细: // 0-未初始化,尚未调用open()方法; // 1-启动,调用了open()方法,未调用send()方法; // 2-发送,已经调用了send()方法,未接收到响应; // 3-接收,已经接收到部分响应数据; // 4-完成,已经接收到全部响应数据; document.getElementById(‘i3‘).value = xhr.responseText // responseText 拿到返回值字符串并赋值给id=‘i3‘的input框 } }; xhr.open(‘GET‘,‘/add2/?i1=‘+document.getElementById(‘i1‘).value+‘&‘+‘i2=‘+document.getElementById(‘i2‘).value); // 以GET的形式向URL 为add2发送数据 xhr.send() // 发送数据 */ // 原生 Ajax 的 POST 方式 var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { // onreadystatechange方法是监控当有返回值时,自动执行回调函数 if (xhr.readyState == 4){ // Number readyState 状态值(整数) // 详细: // 0-未初始化,尚未调用open()方法; // 1-启动,调用了open()方法,未调用send()方法; // 2-发送,已经调用了send()方法,未接收到响应; // 3-接收,已经接收到部分响应数据; // 4-完成,已经接收到全部响应数据; document.getElementById(‘i3‘).value = xhr.responseText // responseText 拿到返回值字符串并赋值给id=‘i3‘的input框 } }; xhr.open(‘POST‘,‘/add2/‘); xhr.setRequestHeader(‘Content-Type‘,‘application/x-www-form-urlencoded‘); // 设置请求头协议 xhr.send(‘i1=‘+document.getElementById(‘i1‘).value+‘&‘+‘i2=‘+document.getElementById(‘i2‘).value) // 发送的数据格式 } </script> </body> </html>
from django.shortcuts import render,HttpResponse,redirect 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‘: a1 = int(request.GET.get(‘i1‘)) a2 = int(request.GET.get(‘i2‘)) return HttpResponse(a1+a2) else: a1 = int(request.POST.get(‘i1‘)) a2 = int(request.POST.get(‘i2‘)) return HttpResponse(a1+a2)
二、伪造的Ajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> {# target="ifr 表示不通过POST提交了,而是把数据交给iframe 由iframe提交#} <iframe id="ifr" name="ifr" style="display: none"></iframe> <input type="text" name="user"/> <a onclick="submiForm();">提交</a> </form> <script> function submiForm() { document.getElementById(‘ifr‘).onload = loadIframe; document.getElementById(‘f1‘).submit() } function loadIframe() { var content = document.getElementById(‘ifr‘).contentWindow.document.body.innerText; } </script> </body> </html>
def fake_ajax(request): if request.method == ‘GET‘: return render(request,‘fake_ajax.html‘) else: print(request.POST) return HttpResponse(‘I am 返回值‘)
三、三种Ajax上传文件方法
import os def upload(request): if request.method == ‘GET‘: return render(request,‘upload.html‘) else: print(request.POST,request.FILES) file_obj = request.FILES.get(‘key‘) print(file_obj) print(file_obj.name) file_path = os.path.join(‘static‘,file_obj.name) with open(file_path,‘wb‘) as f: for chunk in file_obj.chunks(): f.write(chunk) return HttpResponse(file_path)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> <div id="container1"></div> <h1>jQuery Ajax上传文件</h1> <input type="file" id="i2"> <a onclick="upload2();">上传</a> <div id="container2"></div> <h1>伪Ajax上传文件</h1> {# 伪Ajax上传一定要在from中加属性: enctype="multipart/form-data" #} <form id="f1" method="POST" action="/upload/" target="ifr" enctype="multipart/form-data"> <iframe id="ifr" name="ifr" style="display: none;"></iframe> <input type="file" name="key"> <a onclick="upload3()">上传</a> </form> <div id="container3"></div> <script src="/static/jquery-1.12.4.js"></script> <script> // 原生Ajax上传文件 function upload1() { var forData = new FormData(); {# forData.append(‘k1‘,‘v1‘); k1 为键,v1 为字符串对象或者文件对象 #} {# 值为document对象,files为一个列表,[0]表示取第一个文件 #} forData.append(‘key‘,document.getElementById(‘i1‘).files[0]); var xhr = new XMLHttpRequest(); xhr.open(‘POST‘,‘/upload/‘); xhr.send(forData); {# 发送存在forData中的数据 #} xhr.onreadystatechange = function () { {# 回调函数 #} if (xhr.readyState == 4){ {# 当返回值全部加载完成时 #} var file_path = xhr.responseText; {# xhr.responseText取到返回值(返回值为文件路径) #} var tag = document.createElement(‘img‘); {# 创建img标签 #} tag.src = ‘/‘ + file_path; {# 设置img标签的路径 #} document.getElementById(‘container1‘).appendChild(tag); {# 在页面中添加img标签到相应的位置 #} } }; } // jQuery Ajax上传文件 function upload2() { var forData = new FormData(); forData.append(‘key‘,$(‘#i2‘)[0].files[0]); // jquery对象转为document对象时,在后边加[0] // $(‘#i2‘) -> $(‘#i2‘)[0] // document对象转为jquery对象时,直接给document对象加$ // document.getElementById(‘i1‘) -> $(document.getElementById(‘i1‘)) $.ajax({ url:‘/upload/‘, type:‘POST‘, data:forData, contentType:false, processData:false, success:function (arg) { {# 回调函数 #} var tag = document.createElement(‘img‘); {# 创建img标签 #} tag.src = ‘/‘ + arg; {# 设置img标签的路径 #} $(‘#container2‘).append(tag); {# 在页面中添加img标签到相应的位置 #} } }) } // 伪Ajax上传文件 function upload3(){ document.getElementById(‘ifr‘).onload = loadIframe; document.getElementById(‘f1‘).submit(); } function loadIframe(){ var content = document.getElementById(‘ifr‘).contentWindow.document.body.innerText; var tag = document.createElement(‘img‘); tag.src = "/"+ content; $(‘#container3‘).append(tag); } </script> </body> </html>
四、JSONP(解决浏览器的同源策略)和CORS跨域资源共享
- JSONP - 同源策略 - 限制:Ajax(包括原生Ajax和jQuery Ajax) - 不限制:script 标签中的src属性链接到别的网址 开发需求:向其他网站发Http请求 - 浏览器直接发送请求【考虑同源】 - 浏览器->服务端->发送请求【不考虑同源】 浏览器直接发送请求【考虑同源】 要求: 1. 客户端 - URL?callback=funcname - function funcname(arg){ console.log(arg) } 2. 服务端 - 获取 funcname = request.GET.get(callback) - 返回: funcname = request.GET.get(‘callback‘) # 动态获取函数名 user_list = [ ‘alex‘,‘eric‘,‘egon‘ ] user_list_str = json.dumps(user_list) # 转为json字符串 temp = "%s(%s)" %(funcname,user_list_str,) # 返回 "函数名(json字符串参数)" return HttpResponse(temp) 使用: 1. 自己写动态创建script function getUsers(){ var tag = document.createElement(‘script‘); tag.src = "http://www.s4.com:8001/users/?callback=funcname"; document.head.appendChild(tag); } function funcname(arg){ console.log(arg); } 2. jQuery $.ajax({ url: ‘http://www.s4.com:8001/users/‘, type: ‘GET‘, dataType: ‘JSONP‘, # 类型 jsonp: ‘callback‘, # 后台通过request.GET.get(callback)获取到funcname函数名 jsonpCallback: ‘funcname‘ }) function funcname(arg){ console.log(arg); } 其他: - 只能发GET请求 - 约定 JSONP是一种方式,目的解决跨域问题 - CORS 跨域资源共享 简单请求: def new_users(request): obj = HttpResponse(‘返回内容‘) obj[‘Access-Control-Allow-Origin‘] = "*" #不限制任何请求 return obj 复杂请求: HTML: <script> function getUsers(){ $.ajax({ url: ‘http://www.s4.com:8001/new_users/‘, type:"DELETE", success:function(arg){ console.log(arg); } }) } </script> def new_users(request): if request.method == "OPTIONS": #预检 复杂请求来了方法都是OPTIONS obj = HttpResponse() obj[‘Access-Control-Allow-Origin‘] = "*" obj[‘Access-Control-Allow-Methods‘] = "DELETE" return obj obj = HttpResponse(‘想要访问的数据‘) obj[‘Access-Control-Allow-Origin‘] = "*" #不限制任何请求 return obj 其他: - 任何请求