Python学习笔记Day24 - Ajax
- 初识Ajax
- Ajax发送数据
- 原生Ajax
- 基于jQuery的Ajax
- 伪Ajax操作(iframe)
- 三种方式使用的时机
- 文件上传(预览)
- 1. iframe
- 2. jQuery(FormData)
- 图片验证码 + Session
- 1. GET访问页面
- 2. POST提交数据
- JSONP - 最广泛的跨域请求方式
- 编辑框
- 1.基本使用
- 2.文件上传
- 3.XSS攻击(过滤的函数或类)
- 使用kindeditor会隐藏原来的textarea标签,而如果该标签为required,提交时浏览器会报错
- 作业
初识Ajax
验证输入信息
悄悄地提交,不刷新页面$('i1').click(function(){ $.ajax({ url: '/host', type: "POST", data: {'k1': 123,'k2': "root",'k4': JSON.stringfy({'k1': 'v'})}, // 要提交的数据 // .stringfy() 将字典序列化成字符串 // traditional:true // 使发送的data中可以接收列表数据'k3':[1,2,3] // data:$('#add_form').serialize(), // 自动将form表单中的数据打包发送,上传文件看下面 dataType:'JSON', // 自动将接收到的data反序列化成obj返回 success: function(data){ // 此处data为接收到返回的httpRes信息,可传obj // 服务器返回信息后自动触发 // data是服务器端返回的字符串, 如果用dataType:'JSON', 传的参数是obj对象 // var obj = JSON.parse(data); // json将字符串反序列化成字典 #.stringfy()序列化 if (obj.status){ location.reload(); // 刷新 location.href = "某个地址" // 跳转 }else{ $('#error_msg').text(obj.error) // 将收到的错误信息传给error_msg标签 } }, error:function(){ ... //后台未接收到请求或未返回数据等未知错误 } }) })-
其他写法:(不推荐)
$.get(url='',data='',success='function(){}') $.post(url='',data='',success='function(){}') -
建议:永远让服务器端返回一个字典
ret={'status':True,'error':None,'data':None} return HttpResponse(json.dumps(ret)) #json将字典序列化成字符串 -
ajax返回数据推荐用HttpResponse
提交 -> url -> 函数或类中的方法 HttpResponse('{}') render(request, 'index.html', {'name': 'v1'}) "{{ name }}
" -->> "v1
" 只能返回字符串给用户 不能redirect() 用户 <<<<< 字符串 -
ajax只发送数据不涉及表单时,解决csrf_token
引入cookie,在ajax中将cookie中的csrftoken添加至请求头中 $.ajax({ ... headers: {"X-CSRFToken": $.cookie('csrftoken')}, ... })
Ajax发送数据
参考博客
大部分采用XMLHttpRequest,但IE只支持ActiveXObject
原生Ajax
-
创建XMLHttpRequest或ActiveXObject对象
function GetXHR(){ var xhr = null; if(XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } return xhr; } -
提交数据
function XhrPostRequest(){ var xhr = GetXHR(); // 定义回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已经接收到全部响应数据,执行以下操作 var data = xhr.responseText; console.log(data); } }; // 指定连接方式和地址----文件方式 xhr.open('POST', "/test/", true); // 设置请求头,设置发送的数据类型 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); // 发送请求 xhr.send('n1=1;n2=2;'); } -
接收数据
function XhrGetRequest(){ var xhr = GetXHR(); // 定义回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已经接收到全部响应数据,执行以下操作 var data = xhr.responseText; console.log(data); } }; // 指定连接方式和地址----文件方式 xhr.open('get', "/test/", true); // 发送请求 xhr.send(); }
基于jQuery的Ajax
jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能
jQuery 不是生产者,而是大自然搬运工。
jQuery Ajax本质: XMLHttpRequest 或 ActiveXObject
注:2.+版本不再支持IE9以下的浏览器$.ajax({ url: '/upload_file/', type: 'POST', data: fd, success:function(arg,a1,a2){ console.log(arg); console.log(a1); console.log(a2); # a2包含一个xhr对象 } })伪Ajax操作(iframe)
由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。
服务端返回时,触发iframe的onload事件,并将数据放在iframe的#document对象中
也可自定义onload事件,使用$('#ifm1').contents()获取iframe内的标签function sumitForm(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); }) }三种方式使用的时机
如果发送的是【普通数据】 -> jQuery,XMLHttpRequest,iframe
如果发送的是【文件】 -> iframe,jQuery(FormData),XMLHttpRequest(FormData)
文件上传(预览)
上传按钮的input框本身不能直接style修改美化,只能通过relative伪覆盖添加新的标签进行美化
上传文件三种方式:
1. iframe
兼容性好
function iframeSubmit(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); // 实现预览 $('#preview').empty(); var imgTag = document.createElement('img'); imgTag.src = "/" + obj.data; $('#preview').append(imgTag); }) }2. jQuery(FormData)
function jqSubmit(){ // ajax上传文件必须通过FormData对象传输数据 var formdata = new FormData(); formdata.append('username', $('#username').val()); formdata.append('psd', $('#password').val()); formdata.append('file', $('#file')[0].files[0]); $.ajax({ url: '/upload_file/', type: 'POST', headers: { "X-CSRFToken": $.cookie('csrftoken') }, data: formdata, processData: false, // 不处理数据(文件上传必须) contentType: false, // 不设置内容类型,按原格式传输(文件上传必须) success:function(arg,a1,a2){ console.log(arg); console.log(a1); console.log(a2); } }) }3. XMLHttpRequest(FormData)
function xhrSubmit(){ // $('#fafafa')[0] // 获取input上传的文件对象 var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); // 创建FormData对象 fd.append('username','root'); // 添加普通数据,key-value fd.append('fafafa',file_obj); // 添加文件对象,key-obj var xhr = new XMLHttpRequest(); xhr.open('POST', '/upload_file/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完毕 var obj = JSON.parse(xhr.responseText); console.log(obj); } }; xhr.send(fd); }图片验证码 + Session
1. GET访问页面
-> 创建图片并返回给用户 => 用Pillow模块创建一张图片,并在图片中写入随机字符串(封装成check_code.py模块,返回img对象和验证字符串strs)(依赖字体文件) img, code = creat_validate_code() => 将img写入内存 stream = BytesIO() img.save(stream,'PNG') => 读取内存中的图片并显示 data = stream.getValue() HttpResponse(data) -> session存放验证码 => 将code写入session request.session['CheckCode'] = code2. POST提交数据
-> 比对验证码 if request.session['CheckCode'].upper() == request.POST.get('check_code').upper(); ... -> 更换验证码 绑定点击事件 onclick="changeCheckCode(this);" ths.src = ths.src + '?' # 采用地址后面加?的方式,更换地址重新获取验证码JSONP - 最广泛的跨域请求方式
(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性实现跨域请求
import requests response = request.get('http://www.baidu.com') response = request.post('http://www.baidu.com') # print(response.content) # 字节格式的文本 response.encoding = 'utf-8' # 指定编码 print(response.text) # 文本内容(经编码后的字符串) print(response.headers) # 响应头 print(response.cookies) # 所有cookies return render(request, 'req.html',{'result': response.text})由于浏览器具有同源策略(阻止Ajax请求,但无法阻止)
JSONP使用js巧妙实现跨域请求:
-
创建script标签
var tag = document.createElement('script'); -
src=远程地址
tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'; -
将标签添加进header,随后移除
document.head.appendChild(tag); document.head.removeChild(tag); -
返回的数据必须是js格式
必须提前写好函数才能解析返回的js代码,可将函数名用callback参数传给url
JSONP只能发GET请求
利用ajax实现JSONP请求:
$.ajax({ url: 'http://www.jxntv.cn/data/jmd-jxtv2.html', type: 'POST', dataType: 'jsonp', jsonp: 'callback', jsonpCallback: 'list' # 传递函数名 }) 原理同上还有CORS方式跨域请求,直接将域名加白名单
编辑框
CKEditor,UEEditor,TinyEditor,KindEditor(***)
参考博客
1.基本使用
官网下载
-
文件夹说明
├── asp -> asp示例 ├── asp.net -> asp.net示例 ├── attached -> 空文件夹,放置关联文件attached ├── examples -> HTML示例 ├── jsp -> java示例 ├── lang -> 支持语言 ├── license.txt -> License ├── php -> PHP示例 ├── plugins -> KindEditor内部使用的插件 ├── themes -> KindEditor主题 ├── kindeditor-all-min.js -> 全部JS 包含插件(压缩) ├── kindeditor-all.js -> 全部JS 包含插件(未压缩) ├── kindeditor-min.js -> 仅KindEditor JS(压缩) └── kindeditor.js -> 仅KindEditor JS(未压缩) -
HTML
-
详细参数
http://kindeditor.net/docs/option.html
2.文件上传
- 文件上传,多文件上传,文件空间管理
3.XSS攻击(过滤的函数或类)
下节课说...
使用kindeditor会隐藏原来的textarea标签,而如果该标签为required,提交时浏览器会报错
解决办法:
-
form表单添加novalidate属性,但会导致所有验证都不能用,不建议
-
取消该标签的required
作业
主站:
http://127.0.0.1:8000/ 博客首页 http://127.0.0.1:8000/zhaofan/1.html 某人的某篇博客个人博客:
http://127.0.0.1:8000/zhaofan.html 某人的博客 http://127.0.0.1:8000/zhaofan/tag/python.html 某人的博客筛选 http://127.0.0.1:8000/zhaofan/catetory/mvc.html 某人的博客筛选 http://127.0.0.1:8000/zhaofan/date/2011-11.html 某人的博客筛选个人后台管理:
http://127.0.0.1:8000/backend/base-info.html http://127.0.0.1:8000/backend/tag.html http://127.0.0.1:8000/backend/category.html http://127.0.0.1:8000/backend/article.html http://127.0.0.1:8000/backend/add-article.html