文章目录
AJAX准备知识:JSON
- 什么是JSON
- JSON指的是JavaScript对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON独立于语言
- JSON具有自我描述形,更易理解
- JSON使用JavaScript语法来描述数据对象。但是JSON仍然独立于语言和平台。JSON解析器和JSON库支持许多不同的编程语言
js中的undefined格式没法转换成json格式
python中操作json数据
json.dump():往文件中存
json.dumps():往对象中存
json.load(): 从一个字符串中加载数据
json.loads(): 从一个打开的文件中读取数据
js中操作json数据
JSON.parse() : 读,从一个字符串中解析数据
JSON.stringify(): 把js中的数据类型转换成字符串,再转换成字节就可以通过网络传给其他语言了
例 python中的字典通过python的json模块序列化后传给ajax,ajax再通过Jquery中的json模块解析成他看得懂的类型。这样前端就是json格式数据,后端用python进行相关操作
NOTE:序列化:(序列,就是有序排列)就是把数据按一定顺序存储,下次读取保留现有状态,有时间或者空间先后关系,
例2 python中的字典通过Django封装的关于Json模块直接传递给浏览器或ajax
stringify和parse方法
JavaScript中关于JSON对象和字符串转换的两个方法:
JSON.parse(): 用于将一个JSON字符串转换为JavaScript对象
JSON.stringify用于将JavaScript值转换为JSON字符串
和XML的比较
JSON格式于2001年Douglas Crockford提出的,目的就是取代繁琐笨重的XML格式
JSON格式有两个显著优点:书写简单,一目了然。符合JavaScript原生语法,可以由解释引擎直接处理。不用另外添加解析代码,所以,JSON迅速被接受。已经成为各大网站交换数据的标准格式。并被写入ECMAScript5,成为标准的一部分。
XML和JSON都使用结构化方法来标记数据,
类似html的标签的语言。
AJAX简介
目的是不用form表单传递数据给js,最开始没有json,只有xml,现都是传递json格式数据了,特点是用js给服务器发请求,而不是form发请求
AJAX(Asynchronous JavaScript And XML),即使使用JavaScript语言于服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)
AJAX不是编程语言,而是一种使用现有标准的新方法,
异步:一个请求没回来就可以发送下一个请求,如果页面有很多触发ajax请求,就是在前一个请求阻塞的情况下可以下一个请求继续执行。ajax请求拿到数据之后,通过JS的Dom操作去修改页面的内容,给用户一种局部刷新的错觉,可以同时向服务器发送很多请求。缺点是滥用时对服务端压力比较大。
FORM表单请求需要刷新页面得到回应才发生下一个请求,如果没有接收到就阻塞了。
AJAX不能用submit提交,因为type类型submit提交会刷新页面,如果不写type,默认type为submit。一定要指定button的type为button才会按ajax提交。
原生JS实现的AJAX
- templates
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/index/" method="post">
<input type="text" name="num" id="i1">
<input type="submit" value="submit">
</form>
<button id="b2">点我发AJAX</button>
<script>
var b2E = document.getElementById('b2');
b2E.onclick = function () {
// new JS中的创建新的XMLHttpRequest对象
var xmlHttp = new XMLHttpRequest();
// 打开POST请求往/index/发请求
xmlHttp.open('POST', '/index/', true);
// 设置请求的头部。Content-type=..编码方式(form表单默认的enctype)用JS模拟form表单提交数据
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// 发数据,取到用户填写的值,JS中取值是value,innerHTML,innerTEXT
var num = document.getElementById('i1').value;
xmlHttp.send('num='+num);
// 回调,当请求收到后端的响应之后
xmlHttp.onreadystatechange = function () {
// 如果请求的状态码为4,并且响应的状态码为200,
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
// 请求被正常响应了,得到一个结果,此结果是views函数中return的内容,保存在responseText中,然后弹框
alert(xmlHttp.responseText);
}
}
}
</script>
</body>
</html>
- views
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
from app01.models import UserInfo
# Create your views here.
def index(request):
if request.method == 'POST':
inp = request.POST.get('num')
return HttpResponse('您刚刚输入的内容是:%s' % inp)
return render(request, 'index.html')
- urls
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^index/', views.index),
]
浏览器运行结果如图
由于元素JS实现ajax比较繁琐,所以用jQuery实现
- form表单的post请求和AJAX的post请求的发送到服务器的区别
AJAX帮助发送到服务端请求而无需刷新整个页面,只是刷新了局部
- JS原生实现AJAX的原理
- 原生JS实现失去焦点时的操作
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" name="num" id="i1">
<script>
var i1Ele = document.getElementById('i1');
i1Ele.onblur = function () { // 只要光标点击input外,就能触发该匿名函数,
// new JS中的创建新的XMLHttpRequest对象
var xmlHttp = new XMLHttpRequest();
// 使用POST请求往/index/发请求
xmlHttp.open('POST', '/index/', true);
// 设置请求的头部。Content-type=..编码方式(form表单默认的enctype)用JS模拟form表单提交数据
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// 发数据,取到用户填写的值,JS中取值是value,innerHTML,innerTEXT
var num = i1Ele.value;
// 把拼接的值发送给后端
xmlHttp.send('num=' + num);
// 回调,当请求收到后端的响应之后
xmlHttp.onreadystatechange = function () {
// xmlHttp对象有回应了,请求失败和请求发送中都有编码,请求被响应的状态码为4,响应的成功的状态码为200,
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
// 请求被正常响应了,得到一个结果,此结果是views函数中return的内容,保存在responseText中,然后弹框
// 实现了页面没有刷新的情况下,把数据发送给服务端和客户端。
alert(xmlHttp.responseText);
}
}
}
</script>
</body>
</html>
jQuery实现AJAX
- 对于Django来说,无论时AJAX发送的请求还是form表单提交的请求,都是一样的,只要获取到了request.POST或request.GET就可以了。拿到的是QueryDict类型
- html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" name="num" id="i1">
{% load static %}
<script src={% static 'jquery.js' %}></script>
<script>
// JQuery中的匿名函数,失去焦点时。
$('#i1').on('blur', function() {
// 发送ajax请求
$.ajax({
// 往哪里发请求
url: '/JQueryAJAX/',
// 发送的方式
type: 'POST',
// 发送的数据
data: {'num':$('#i1').val()
},
// 当请求被成功响应后,执行success的匿名函数,res是视图函数中返回值。
success: function (res) {
alert(res)},
// 请求失败后执行error后匿名函数
error: function (err) {
alert(err)
}
})
})
</script>
</body>
</html>
- urls
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^JSAJAX/', views.JSAJAX),
url(r'^JQueryAJAX', views.JQueryAJAX)
]
- views
def JQueryAJAX(request):
if request.method == 'POST':
inp = request.POST.get('num')
print(inp)
return HttpResponse(inp)
return render(request, 'JQuery实现AJAX.html')
前端知识复习
input
当前请求的IP地址
request.META.get(‘REMOTE_ADDR’)
p标签中不能包含p标签
JS控制网页的跳转
委托事件
一个选择器使用多次时,赋值给一个变量
添加属性
attr操作属性的,prop获取type为checkbox中是否被选中,选中就返回true。
JQuery中的val
JQuery中与i1同级的下面的p标签设置文本内容为res
Django项目中ajax如何处理csrftoken
- html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>欢迎登录</h1>
<div>
<p>
<label for="i1">用户名</label>
<input type="text" id="i1">
</p>
<p>
<label for="i2">密码</label>
<input type="password" id="i2">
</p>
<p>
<label for="b1"></label>
<button id="b1">登录</button>
<span style="color:red"></span>
</p>
{% csrf_token %}
</div>
{% load static %}
<script src={% static 'jquery.js' %}></script>
<script>
$('#b1').click(function(){
var c = $('[name="csrfmiddlewaretoken"]').val();
$.ajax({
url: '/login1/',
type: 'post',
// 用ajax携带csrfmiddlewaretoken
data: {n:$('#i1').val(), p:$('#i2').val(), csrfmiddlewaretoken:c},
success: function (res) {
if (res.code === 0){
location.href = res.next_url
}else {
$('#b1+span').text(res.err_msg)
}
}
})
})
</script>
</body>
</html>
- url
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^JSAJAX/$', views.JSAJAX),
url(r'^JQueryAJAX/$', views.JQueryAJAX),
url(r'^register/$', views.register),
url(r'^login1/$', views.Login1.as_view())
]
- views
class Login1(views.View):
def get(self, request):
return render(request, '在请求中加csrf.html')
def post(self, request):
n = request.POST.get('n')
p = request.POST.get('p')
is_ok = User.objects.filter(name=n, pwd=p)
res = {'code': 0}
if is_ok:
res['next_url'] = '/register/'
print(res)
return JsonResponse(res)
else:
res['code'] = 1
res['err_msg'] = '用户名或密码错误'
print(res)
return JsonResponse(res)
AJAX如何上传文件
ajax上传文件的方式和form表单上传文件的方式不一样。
- views
def upload(request):
if request.method == 'POST':
file_obj = request.FILES.get('xx')
file_name = file_obj.name
with open(file_name, 'wb') as f:
for c in file_obj.chunks():
f.write(c)
return HttpResponse('上传成功')
return render(request, 'AJAX上传文件.html')
- urls
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^JSAJAX/$', views.JSAJAX),
url(r'^JQueryAJAX/$', views.JQueryAJAX),
url(r'^register/$', views.register),
url(r'^login1/$', views.Login1.as_view()),
url(r'^upload/$', views.upload)
]
- html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>上传文件</h1>
<input type="file" id="f1">
<button id="b1">上传</button>
{% csrf_token %}
{% load static %}
<script src="{% get_static_prefix %}jquery.js"></script>
<script>
$('#b1').click(function () {
var f = new FormData(); // 上传文件时新建一个FormData对象
var c = $('[name="csrfmiddlewaretoken"]').val();
// 在新的f中添加键值
f.append('xx', $('#f1')[0].files[0]); // 取到要上传的文件对象
f.append('csrfmiddlewaretoken', c);
$.ajax({
url: '/upload/',
type: 'post',
data: f,
processData: false, // 告诉jquery不要处理我上传的数据
contentType: false, // 告诉jquery不要设置请求的内容的文件类型。就会遵循FormData中的类型设置
success: function (res) {
console.log(res)
}
})
})
</script>
</body>
</html>