目录
1 简介
2 工作流程
3 基于Javascript实现Ajax
4 基于jQuery实现Ajax→$.ajax()
4.1 引入jQuery文件
4.2?$.ajax()参数:
4.3?其他形式的$.ajax()
5 临时调用JavaScript文件
6 JSON知识补充
7 跨域请求
7.1 浏览器的同源策略
7.2 JSONP
1 简介
Ajax:全名Asynchronous JavaScript And XML(异步JavaScript和XML),使用Javascript语言与服务器进行异步交互,包括HTML、XHTML、CSS、JavaScript、DOM、XML、XSTL、XMLHttpRequest等多种技术。
Ajax优点:与服务器异步交互;页面局部刷新、性能高
Ajax缺点:不适用异步交互场景;局部刷新次数多会导致服务器压力大;使用Javascript就涉及到浏览器的兼容性问题。
同步交互:客户端发出一个请求后,需等待服务器响应结束才能发出第二个请求
异步交互:客户端发出一个请求后,无需等待服务器响应结束就能发出第二个请求
应用场景:搜索框文字提示功能;用户输入表单提示功能
// 不同版本浏览器创建XMLHttpRequest对象的方式不同
function createXMLHttpResquest(){
var xmlHttp;
try{
xmlHttp = new XMLHttpRequest(); // IE7及以上、大多数浏览器
}catch (e){
try{
xmlHttp = new ActiveXObject('Msxm12.XMLHTTP'); // E6
}catch (e){
try{
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); // IE5.5及更早
}catch (e){
}
}
}
return xmlHttp;
}
2 工作流程
四步操作:创建核心对象→打开与服务器的连接→发送请求→监听服务器响应
核心对象XMLHttpRequest的readyState属性:
????????保存核心对象XMLHttpRequest的状态,不同阶段其值如下:
? ? ? ? 0:创建了XMLHttpRequest对象。
? ? ? ? 1:调用了open方法,请求开始。
? ? ? ? 2:调用了send方法,请求完成。
? ? ? ? 3:开始读取服务器响应。
? ? ? ? 4:读取服务器响应结束。
核心对象XMLHttpRequest的onreadystatechange事件:
? ? ? ? 给XMLHttpRequest绑定上onreadystatechange事件后,当readyState的值发生变化时会触发onreadystatechange事件。
3 基于Javascript实现Ajax
示例内容:前端将用户名发送到后端,后端拿到用户名判断用户名是否重复并返回结果到前端,前端拿到返回值后,如果用户名重复,则进行页面局部刷新,提示用户名已存在。
# urls.py
from app01 import views
urlpatterns = [
path("admin/", admin.site.urls),
path('register/', views.register),
]
# views.py
from django.shortcuts import render, HttpResponse
def register(req):
if req.method == 'POST':
username = req.POST.get("username")
if username == '春生':
return HttpResponse('1')
return HttpResponse('0')
return render(req, 'register.html')
# 在settings.py中注释下面这行代码
# "django.middleware.csrf.CsrfViewMiddleware",
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>
用户名:<input type="text" id="user" name="username" onblur="func1()">
<span id="warning" style="color: red"></span>
</p>
<p>
密码:<input type="password" name="pwd">
</p>
</body>
<script>
function func1(){
// 第1步:创建new XMLHttpRequest()对象,此处省略了文章第一段代码中的函数
var xmlhttp = createXMLHttpResquest();
// 第4步:监听(监听事件推荐放在创建对象之后、打开连接之前),根据后端返回值判断用户名是否已存在
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var data = xmlhttp.responseText;
if (data == '1'){
document.getElementById('warning').innerText = '用户名已存在!'
}
}
}
// 第2步:打开连接
xmlhttp.open('POST', '/register/', true);
// 第3步:发送请求(以POST方式发送数据时,需要在open和send之间设置请求头的格式)
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
var username = document.getElementById('user').value;
xmlhttp.send('username='+username);
}
</script>
</html>
开启服务器,浏览器访问服务器并输入“春生”,移出鼠标,页面提示“用户名已存在!”
4 基于jQuery实现Ajax→$.ajax()
4.1 引入jQuery文件
# 在项目文件夹下创建static文件夹,放入jQuery文件,并在setting.py文件中添加以下代码引入jQuery文件
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
4.2?$.ajax()参数:
data:提交的数据,是一个json的object对象,ajax方法会默认把它编码成某种格式发给服务端;ajax默认以get方式发送请求。
$.ajax({
url:'/jquery_ajax/',
data:{a:1,b:2},
})
// req.GET:<QueryDict: {'a': ['1'], 'b': ['2']}>
processData:声明当前的data数据是否进行转码或预处理,默认为true即进行预处理;当data是一个dom结构或者xml数据时,我们希望不要进行处理,就将其设置为false。
$.ajax({
url:'/jquery_ajax/',
data:{a:1,b:2},
processData:false,
})
// req.GET:<QueryDict: {}> 怎么是空的????
contentType:指明当前请求的数据编码格式,默认为'application/x-www-form-urlencoded';当设置contentType值为'application/json',data必须为json字符串,不能是json的object对象。
traditional:默认为false,会对数据进行深层次迭代;一般在数据有数组时设置为true。
$.ajax({
url:'/jquery_ajax/',
data:{a:1,b:[3,4]},
})
// req.GET:<QueryDict: {'a': ['1'], 'b[]': ['3', '4']}>
$.ajax({
url:'/jquery_ajax/',
data:{a:1,b:[3,4]},
traditional:true,
})
// req.GET:<QueryDict: {'a': ['1'], 'b': ['3', '4']}>
dataType:预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
// 场景1
// views.py
def jquery_ajax(req):
return HttpResponse('hello')
// html
$.ajax({
url:'/jquery_ajax/',
dataType:'json',
success:function (data){
console.log(data) // 无打印内容
}
})
// 场景2 HttpResponse('hello')改为HttpResponse('"hello"')
// views.py
def jquery_ajax(req):
return HttpResponse('"hello"')
// html
$.ajax({
url:'/jquery_ajax/',
dataType:'json',
success:function (data){
console.log(data) // hello
}
})
dataFilter:给Ajax返回的原始数据进行预处理的函数。
type:请求方式,'GET'或'POST',默认为'GET'。
beforeSend:发送请求前对XMLHttpRequest对象进行修改的函数(如添加自定义HTTP头),如果返回false可以取消本次Ajax请求。
jsonp:在一个jsonp请求中重写回调函数名,这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的“callback”部分,比如{jsonp:'onJsonpLoad'}会导致将"onJsonpLoad=?"传给服务器。
jsonpCallback:为jsonp请求指定一个回调函数名,这个值用来取代jQuery自动生成的随机函数名,更方便地提供回调函数和错误处理;你也可以在想让浏览器缓存GET请求的时候指定这个回调函数名。
success:响应成功后执行的函数。
error:响应失败后执行的函数。
complete:响应完成后执行的函数(不管成功还是失败都执行)。
statusCode:给不同的响应状态码指定执行函数。
# views.py中指定响应状态码,模拟不同响应状态
def jquery_ajax(req):
HttpResponse.status_code = 400
return HttpResponse('hello')
$.ajax({
url:'/jquery_ajax/',
statusCode:{
'400':function () {
console.log('400')
},
'403':function () {
console.log('403')
},
}
})
// 400
4.3?其他形式的$.ajax()
1 $.get():相当于$.ajax()中提交方式为GET
$.get(url,[data],[function],[type])
// url: 提交地址
// data: 提交的数据,可以直接跟在url后面
// function: 回调函数
// type: 可以指定返回值的类型,如果服务端返回的类型不符,则不接收
// 示例1:在data中提交数据,默认会对data里的数据进行编码
$.get('/jquery_ajax/',{a:'1'})
// req.GET:<QueryDict: {'a': ['1']}>
// 示例2:url后面直接跟提交的数据(需要注意编码问题,尽量在data中提交,可以自动编码)
$.get('/jquery_ajax/?a=1')
// req.GET:<QueryDict: {'a': ['1']}>
// 示例3:回调函数参数内容
$.get('/jquery_ajax/',{a:'1'},function (data,state,obj){
console.log(data);
console.log(state);
console.log(obj);
})
//OK
//success
//{readyState: 4, getResponseHeader: ?, getAllResponseHeaders: ?, setRequestHeader: ?, overrideMimeType: ?,?…}
2 $.post():相当于$.ajax()中提交方式为POST
$.POST(url,[data],[function],[type])
// url: 提交地址
// data: 提交的数据
// function: 回调函数
// type: 可以指定返回值的类型,如果服务端返回的类型不符,则不接收
3?$.getJson():相当于$.get()中type格式为Json
5 临时调用JavaScript文件
$.getScript(url,callback)
// url: 文件路径
// callback: 回调函数
// myfunction.js
function add(a,b){
return a+b;
}
// html
$.getScript('/static/myfunction.js',function (){
console.log(add(1,2));
})
6 JSON知识补充
6.1 JSON:JavaScript Object Notation,即基于JavaScript语言的轻量级的数据交换格式。JSON是用字符串来表示JavaScript对象,JavaScript可以执行这个字符串的到一个JavaScript对象。
6.2 JSON语法:
????????数据在键值对中
????????数据由逗号分隔
????????大括号保存对象
????????中括号保存数组
6.3 从python数据类型向JSON类型转换关系:
Python | JSON | dict | object | list,tuple | array | str,unicode | string | int,long,float | number | True | true | False | false | None | null |
6.4 Python中的json方法:
json.dumps:将Python对象转换成JSON字符串
json.loads:将JSON字符串转换成Python对象
# views.py
import json
def jquery_ajax(req):
dic = {'a': '1', 'b': '2'}
return HttpResponse(json.dumps(dic))
$.post('/jquery_ajax/',function (data){
console.log(data);
console.log(typeof data);
console.log(data['a']);
})
// {"a": "1", "b": "2"}
// string
// undefined
$.post('/jquery_ajax/',function (data){
console.log(data);
console.log(typeof data);
// 将JSON字符串对象转换为JSON的object对象
data=JSON.parse(data);
console.log(typeof data);
console.log(data['a']);
})
// {"a": "1", "b": "2"}
// string
// object
// 1
6.5 JavaScript中的JSON方法
JSON.parse:将字符串转换成JSON对象
JSON.stringify:将JSON对象转换成JSON字符串
var str = '{"a":"1","b":"2"}'
console.log(JSON.parse(str));
// {a: '1', b: '2'}
var a = {a:1,b:2}
console.log(JSON.stringify(a))
// {"a":1,"b":2}
6.6 JSON与XML比较:
XML:可读性更好,已流行好多年
JSON:在Javascript主场作战,可以存储Javascript复合对象,有着XML不可比拟的优势
7 跨域请求
7.1 浏览器的同源策略
? ? ? ? 同源指协议、域名、端口全部相同,不同源的客户端脚本在没有明确授权的情况下不能读取对方的数据。
7.2 JSONP
? ? ? ? JSONP全称JSON with Padding,可以在服务器集成Script tags返回至客户端,通过JavaScript callback的形式实现跨域访问
通过JavaScript实现JSONP:
// html
function fetch(arg){
alert(arg);
}
function addScriptTag(src){
var oScript = document.createElement('script');
oScript.type = 'text/javascript';
oScript.src = src;
document.body.appendChild(oScript);
}
window.onload = function (){
addScriptTag('http://127.0.0.1:8001/jquery_ajax?callback=fetch')
}
# views.py
def jquery_ajax(req):
callback = req.GET.get('callback', None)
return HttpResponse('%s("ajax")' % callback)
# setting.py 添加代码
SECURE_CONTENT_TYPE_NOSNIFF = False
通过jQuery实现JSONP方式1:$.getJSON()
// html
// url后面必须添加一个callback参数,这样getJSON方法才会以JSONP的方式去访问服务端,后面的?是内部会自动生成一个回调函数名
$.getJSON('http://127.0.0.1:8001/jquery_ajax?callback=?', function (arg) {
alert(arg);
})
# views.py
def jquery_ajax(req):
callback = req.GET.get('callback', None)
print(callback)
# 打印结果 jQuery36007684783752448021_1662972604726,即生成的回调函数名
return HttpResponse('%s("ajax1")' % callback)
# setting.py 添加代码
SECURE_CONTENT_TYPE_NOSNIFF = False
通过jQuery实现JSONP方式2:$.ajax()
// html
$.ajax({
url:'http://127.0.0.1:8001/jquery_ajax',
dataType:'jsonp',
jsonp:'callback',
success:function (arg){
alert(arg);
}
})
# views.py
def jquery_ajax(req):
callback = req.GET.get('callback', None)
print(callback)
# 打印结果 jQuery360017650463498229318_1662973430145,即生成的回调函数名
return HttpResponse('%s("ajax1")' % callback)
# setting.py 添加代码
SECURE_CONTENT_TYPE_NOSNIFF = False
|