ajax操做基于浏览器的xmlHttpRequest对象,IE低版本是另一个对象。javascript
XmlHttpRequest对象的主要方法:php
void open(String method,String url,Boolen async)
用于建立请求html
参数:
method: 请求方式(字符串类型),如:POST、GET、DELETE...
url: 要请求的地址(字符串类型)
async: 是否异步(布尔类型)java
void send(String body)
用于发送请求jquery
参数: body: 要发送的数据(字符串类型)
void setRequestHeader(String header,String value)
用于设置请求头ajax
参数: header: 请求头的key(字符串类型) vlaue: 请求头的value(字符串类型)
String getAllResponseHeaders()
获取全部响应头django
返回值: 响应头数据(字符串类型)
String getResponseHeader(String header)
获取响应头中指定header的值json
参数: header: 响应头的key(字符串类型) 返回值: 响应头中指定的header对应的值
void abort()浏览器
终止请求
XmlHttpRequest对象的主要属性:服务器
a. Number readyState
状态值(整数)
详细:
0-未初始化,还没有调用open()方法;
1-启动,调用了open()方法,未调用send()方法;
2-发送,已经调用了send()方法,未接收到响应;
3-接收,已经接收到部分响应数据;
4-完成,已经接收到所有响应数据;
b. Function onreadystatechange
当readyState的值改变时自动触发执行其对应的函数(回调函数)
c. String responseText
服务器返回的数据(字符串类型)
d. XmlDocument responseXML
服务器返回的数据(Xml对象)
e. Number states
状态码(整数),如:200、404...
f. String statesText
状态文本(字符串),如:OK、NotFound...
ajax.html
<body> <input type="text" /> <input type="button" value="Ajax1" onclick="Ajax1();" /> <script> function Ajax1(){ var xhr = new XMLHttpRequest(); // 建立XMLHttpRequest对象 xhr.open('GET','/ajax_json/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完毕 var obj = JSON.parse(xhr.responseText); console.log(obj) } }; xhr.setRequestHeader('k1','v1'); // 设置数据头 xhr.send("name=root;pwd=123"); } </script> </body>
urls.py
url(r'^ajax_json/', views.ajax_json), url(r'^ajax/', views.ajax),
views.py
def ajax(request): return render(request, "ajax.html") def ajax_json(request): print(request.POST) ret = {'code':True, 'data':None} import json # return HttpResponse(json.dumps(ret),status=404,reason='Not Found') # 定义状态码及状态信息 return HttpResponse(json.dumps(ret))
上面发送的是GET请求,若是是POST请求呢?
如上若是是POST请求,views里print(request.POST)
是没有数据的,由于POST请求须要给加上请求头。
<script> function Ajax1(){ var xhr = new XMLHttpRequest(); // 建立XMLHttpRequest对象 xhr.open('POST','/ajax_json/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完毕 var obj = JSON.parse(xhr.responseText); console.log(obj) } }; xhr.setRequestHeader('k1','v1'); // 设置数据头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); xhr.send("name=root;pwd=123"); } </script>
如下几种写法,都是同样的效果
> XMLHttpRequest XMLHttpRequest() > window.XMLHttpRequest XMLHttpRequest() > window['XMLHttpRequest'] XMLHttpRequest()
ActiveXObject(“Microsoft.XMLHTTP”)
IE6, IE5
<script type="text/javascript"> 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(); } </script>
若是在jQuery的ajax的回调函数里,再写上一些参数,里面的参数接收的就是xmlHttpRequest对象,功能和上面是如出一辙的。
iframe标签,会把网址嵌套在网页中,iframe里的网址更改,网页是不刷新的。
<iframe src="http://blog.csdn.net/fgf00"></iframe>
示例:输入http://……
网址,跳转
<body> <input type="text" id="url" /> <input type="button" value="Iframe请求" onclick="iframeRequest();" /> <iframe src="http://blog.csdn.net/fgf00" id="ifm"></iframe> <script src="/static/jquery-1.12.4.js"></script> <script> function iframeRequest(){ var url = $('#url').val(); console.log(url); $('#ifm').attr('src',url); } </script> </body>
能够把form提交转交给iframe,iframe提交,利用这个特性,实现伪ajax操做。
ajax.html
<form action="/ajax_json/" method="POST" target="ifm1"> {% csrf_token %} <iframe id="ifm1" name="ifm1"></iframe> <input type="text" name="username" placeholder="用户名"/> <input type="text" name="email" placeholder="邮箱地址"/> <input type="submit" value="Form提交"> </form>
views.py
def ajax_json(request): print(request.POST) ret = {'code':True, 'data':request.POST.get('username')} import json return HttpResponse(json.dumps(ret))
在一些新版本的浏览器里,iframe标签竟然自动跳转,禁用以下:
在iframe标签中增长两个属性:
security="restricted" sandbox=""
前者是IE的禁止js的功能,后者是HTML5的功能。恰好就可让IE,Chrome,Firefox这三大浏览器都实现了禁止iframe的自动跳转。
浏览器审查元素中,iframe加载的时候在document对象里,至关于一个上下文或者空间管理,在HTML里面又嵌套了一个HTML。不能经过之前的方法获取到。
iframe接收到服务端返回的数据后,会执行onload
事件,获取返回数据以下:
<form action="/ajax_json/" method="POST" target="ifm1"> {% csrf_token %} <iframe id="ifm1" name="ifm1" onload="iframeLoad();"></iframe> <input type="text" name="username" placeholder="用户名"/> <input type="text" name="email" placeholder="邮箱地址"/> <input type="submit" value="Form提交" onclick="submitForm();"/> </form> <script src="/static/jquery-1.12.4.js"></script> <script> function submitForm(){ // 当点击提交的时候,才给iframe绑定load事件 // 比在html中这样添加好一点:<iframe name="ifm1" onload="iframeLoad();"></iframe> $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); // document对象下面的值 var obj = JSON.parse(text); console.log(obj); }) } function iiframeLoad(){ console.log(123) } </script>
若是发送的是【普通数据】 : jQuery > XMLHttpRequest > iframe
urls.py
url(r'^upload/$', views.upload), url(r'^upload_file/', views.upload_file),
views.py
def upload(request): return render(request,'upload.html') def upload_file(request): username = request.POST.get('username') fafafa = request.FILES.get('fafafa') import os img_path = os.path.join('static/imgs/',fafafa.name) with open(img_path,'wb') as f: for item in fafafa.chunks(): f.write(item) ret = {'code': True , 'data': img_path} # 返回文件路径(图片预览用) import json return HttpResponse(json.dumps(ret))
upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .upload{ display: inline-block;padding: 10px; background-color: #2459A2; color: white; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 90; } .file{ width: 60px;height: 30px;opacity: 0; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 100; } </style> </head> <body> <div style="position: relative;width: 60px;height: 30px;"> <input class="file" type="file" id="fafafa" name="afafaf" /> <a class="upload">上传</a> </div> <input type="button" value="提交XHR" onclick="xhrSubmit();" /> <input type="button" value="提交jQuery" onclick="jqSubmit();" /> <hr/> <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1"> <iframe id="ifm1" name="ifm1" style="display: none;"></iframe> <input type="file" name="fafafa"/> <input type="submit" onclick="iframeSubmit();" value="iframe提交"/> <!--iframe方式提交--> <hr>选中后,就上传、图片预览 <!--iframe方式提交,选中后,就上传,并图片预览--> <input type="file" name="fafafa" onchange="changeUpalod();" /> <!--iframe方式提交,选择后,就图片预览--> </form> <div id="preview"></div> <!-- 图片预览使用 --> <script src="/static/jquery-1.12.4.js"></script> <script> // 选中后,就上传文件,并图片预览 function changeUpalod(){ $('#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); }); $('#form1').submit(); } // 第二种方式:基于jQuery方式上传文件 function jqSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementById('fafafa').files[0]; // files表明上传的文件 var fd = new FormData(); // 至关于表单 fd.append('username','root'); fd.append('fafafa',file_obj); $.ajax({ url: '/upload_file/', type: 'POST', data: fd, // 上传文件时,添加如下两个参数是告诉jQuery,不要作特殊处理 processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success:function(arg,a1,a2){ console.log(arg); console.log(a1); console.log(a2); // 多写几个参数,这个参数包含xmlHttpRequest对象 } }) } // 第一种方式:基于xmlHttpRequest方式上传文件 function xhrSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); fd.append('username','root'); fd.append('fafafa',file_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); } // 第三种方式:基于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); }) } </script> </body> </html>
xmlHttpRequest和jQuery上传文件,都是基于FormData,可是FormData对于IE一些低版本浏览器是不支持的。
通常状况下,上传图片、头像都是用iframe来实现的。
若是发送的是【文件】 : iframe > jQuery(FormData) > XMLHttpRequest(FormData)
流程:
`/login/
实现:
页面生成返回和生成图片:生成网页html、生成图片url分开,这样更新验证码图片是,网页是不用刷新的。
views
from io import BytesIO from django.shortcuts import HttpResponse from utils.check_code import create_validate_code def check_code(request): """ 验证码 :param request: :return: """ # 直接打开图片,返回 # data = open('static/imgs/avatar/20130809170025.png','rb').read() # return HttpResponse(data) # 经过模块生成图片并返回 # 1. 建立一张图片 pip3 install Pillow # 2. 在图片中写入随机字符串 # obj = object() # 3. 将图片写入到指定文件 # 4. 打开指定目录文件,读取内容 # 5. HttpResponse(data) stream = BytesIO() # 在内存里开辟一块空间,在内存里直接读写,至关于打开一个文件 img, code = create_validate_code() img.save(stream,'PNG') # 把生成的图片进行保存 request.session['CheckCode'] = code # 把验证码放入session中 return HttpResponse(stream.getvalue()) # 在内存中读取并返回
create_validate_code
font_type="Monaco.ttf", # 依赖的字体
html
<img src="/check_code.html" onclick="changeCheckCode(this);"> <script> function changeCheckCode(ths){ ths.src = ths.src + '?'; // URL不变:浏览器不发请求;加上?号,get参数请求,向后台发请求 } </script>
check_code.py(依赖:Pillow,字体文件)
pip3 install Pillow
经常使用的富文本编辑器:CKEditor,UEEditor,TinyEditor,KindEditor
├── asp asp示例 ├── asp.net asp.net示例 ├── attached 空文件夹,放置关联文件attached ├── examples HTML示例 ├── jsp java示例 ├── kindeditor-all-min.js 所有JS(压缩) ├── kindeditor-all.js 所有JS(未压缩) ├── kindeditor-min.js 仅KindEditor JS(压缩) ├── kindeditor.js 仅KindEditor JS(未压缩) ├── lang 支持语言 ├── license.txt License ├── php PHP示例 ├── plugins KindEditor内部使用的插件 └── themes KindEditor主题
<textarea name="content" id="content"></textarea> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/plugins/kind-editor/kindeditor-all.js"></script> <script> $(function () { initKindEditor(); }); function initKindEditor() { var kind = KindEditor.create('#content', { width: '100%', // 文本框宽度(能够百分比或像素) height: '300px', // 文本框高度(只能像素) minWidth: 200, // 最小宽度(数字) minHeight: 400 // 最小高度(数字) }); } </script>
http://kindeditor.net/docs/option.html
items¶ # 配置显示多少个工具 noDisableItems¶ # designMode 为false时,要保留的工具,置灰 filterMode¶ # true时根据 htmlTags 过滤HTML代码,false时容许输入任何代码。 resizeType¶ # 2或1或0,2时能够拖动改变宽度和高度,1时只能改变高度,0时不能拖动。 syncType¶ # 设置”“、”form”,值为form时提交form时自动提交,空时不会自动提交。 uploadJson¶ # 指定上传文件的服务器端程序。 autoHeightMode¶ # 内容多时,自动调整高度。
uploadjson
def upload_img(request):
request.GET.get('dir')
print(request.FILES.get('fafafa'))
# 获取文件保存
import json
dic = {
'error': 0,
'url': '/static/imgs/20130809170025.png',
'message': '错误了...'
}
return HttpResponse(json.dumps(dic))
import os, time, json
def file_manager(request):
"""
文件管理,照片空间
:param request:
:return:
"""
dic = {}
root_path = 'C:/Users/Administrator/PycharmProjects/day24/static/'
static_root_path = '/static/'
request_path = request.GET.get('path')
if request_path:
abs_current_dir_path = os.path.join(root_path, request_path)
move_up_dir_path = os.path.dirname(request_path.rstrip('/'))
dic['moveup_dir_path'] = move_up_dir_path + '/' if move_up_dir_path else move_up_dir_path
else: abs_current_dir_path = root_path dic['moveup_dir_path'] = '' dic['current_dir_path'] = request_path dic['current_url'] = os.path.join(static_root_path, request_path) file_list = [] for item in os.listdir(abs_current_dir_path): abs_item_path = os.path.join(abs_current_dir_path, item) a, exts = os.path.splitext(item) is_dir = os.path.isdir(abs_item_path) if is_dir: temp = { 'is_dir': True, 'has_file': True, 'filesize': 0, 'dir_path': '', 'is_photo': False, 'filetype': '', 'filename': item, 'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path))) } else: temp = { 'is_dir': False, 'has_file': False, 'filesize': os.stat(abs_item_path).st_size, 'dir_path': '', 'is_photo': True if exts.lower() in ['.jpg', '.png', '.jpeg'] else False, 'filetype': exts.lower().strip('.'), 'filename': item, 'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path))) } file_list.append(temp) dic['file_list'] = file_list return HttpResponse(json.dumps(dic))