Ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指⼀种创建交互式⽹⻚应⽤的⽹⻚开发技术。
Ajax 是⼀种⽤于创建快速动态⽹⻚的技术。
Ajax 是⼀种在⽆需重新加载整个⽹⻚的情况下,能够更新部分⽹⻚的技术。
通过在后台与服务器进⾏少量数据交换,Ajax 可以使⽹⻚实现异步更新。这意味着可以在不重新加载整个⽹⻚的情况下,对⽹⻚的某部分进⾏更新。
传统的⽹⻚(不使⽤ Ajax)如果需要更新内容,必须重载整个⽹⻚⻚⾯。
Ajax的优点:
异步
:发送⼀个请求,不需要等待响应返回,随时可以再发送下⼀个请求,即不需要等待。
局部刷新
:通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。【传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。】
应用场景:
这是一个cnblog账户注册界面,当我们在填写昵称的时候输入regina,这个过程本身并没有进行表单提交或者向服务器发送请求,但是当光标离开这个input框之后,就会自动检测了这里面的内容,并且返回提示这个昵称被占用了,而在图二到图三的过程当中,前端显示为下图,有一个刷新的过程,这个就是由于Ajax的局部刷新作用
这个过程中到底浏览器做了些什么工作
我们筛选出XHR(XmlHttpResponse)类型的报文,看到其实浏览器是进行了一个checkDisplayName
的操作发送给了服务器,然后服务器的返回如下
json回顾
映射关系
Python | Json |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True | True |
False | False |
None | Null |
dic = {
\'user\':\"regina\",
\'age\':22,
\'is_married\':True
}
print(json.dumps(dic),type(json.dumps(dic)))
{\"user\": \"regina\", \"age\": 22, \"is_married\": true} <class \'str\'>
可以看到字典中的单引号全部变成了双引号,True映射成了true
dic = [{\'user\':\"regina\"},{\'age\':20}]
print(repr(json.dumps(dic)))
dic = ({\'user\':\"regina\"},{\'age\':20})
print(repr(json.dumps(dic)))
\'[{\"user\": \"regina\"}, {\"age\": 20}]\'
\'[{\"user\": \"regina\"}, {\"age\": 20}]\'
列表和元组全变为了数组形式。
Ajax请求
首先确定一个概念就是Ajax请求不是表单提交,是JS代码提交的,说明是要构建一个js代码函数进行提交请求,所以这里的submit是没有用的,现在构建一段js代码
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<script src=\"https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js\"></script>
<title>Title</title>
</head>
<body>
<h3>注册界面</h3>
用户名<input type=\"text\" class=\"user\"><br>
密码 <input type=\"password\"><br>
<input type=\"submit\">
<script>
$(\".user\").blur(function () {
alert(123);
})
</script>
</body>
</html>
首先做一个测试,当光标移除用户名时,会弹窗。
现在改为ajax请求的方式
<script>
$(\".user\").blur(function () {
$.ajax({
url:\"http://127.0.0.1:8001/user/check/\",
//请求方式默认get
})
})
</script>
然后我们设置好路由,在用户名中输入内容并离开框,看是否有新的请求发出。
我们的目的是要将input标签里的用户名传给后端
$(\".user\").blur(function () {
$.ajax({
url:\"http://127.0.0.1:8001/user/check/\",
//请求方式默认get
data:{
\"name\" : $(\".user\").val()
},
})
})
经过测试,我们的数据已经传回给了后端,并且也可以打印出来,现在要做的就是进行一个验证再反馈到前端
def check(request):
ret = User.objects.filter(username=request.GET.get(\"name\"))
if ret:
return HttpResponse(\"用户已存在\")
else:
return HttpResponse(\"\")
这样的话请求我们就做好了
$.ajax({
url:\"http://127.0.0.1:8001/user/check/\",
//请求方式默认get
data:{
\"name\" : $(\".user\").val()
},
//当相响应正常时触发当函数
success:function (res) {
console.log(res)
}
})
success参数得到了后端响应回来的数据,并打印了出来,现在可以通过dom对象的操作,将返回内容添加到登陆界面进行提示。在用户名标签的后面添加一个span标签,然后选中标签进行添加内容
$(\".err\").html(res)
响应json数据
if ret:
res[\"exist\"] = True
res[\"msg\"] = \"该用户已存在\"
return HttpResponse(json.dumps(res))
为什么要用序列化,首先json可以发送很多的接口数据,并且如果要自己一个一个参数传会很麻烦。按照正常逻辑,上图代码中我们首先写好了json.dumps
将序列化转为字符串,并且在html文件中进行反序列化,
success:function (res) {
console.log(res);
data = JSON.parse(res);
console.log(res);
if(data.exist){
$(\".err\").html(data.msg);
}
else{
$(\".err\").html(\" \");
}
这样我们也可以拿到序列化中的值,但是ajax好的一点就是当我们用JsonResponse(res)
,在html中我们可以直接调用参数,不需要再进行parse反序列化。
练习实例
用ajax实现一个加法
<input type=\"text\" class=\"add n1\"> + <input type=\"text\" class=\"add n2\"> = <input type=\"text\" class=\"add ans\" > <button class=\"btn\">计算</button>
$(\".btn\").click(function () {
$.ajax({
url:\"http://127.0.0.1:8001/user/add/\",
type:\"post\",
data:{
\"num1\":$(\".n1\").val(),
\"num2\":$(\".n2\").val(),
},
success: function(res){
$(\".ans\").val(res);
}
})
})
def add(request):
num1 = int(request.POST.get(\"num1\"))
num2 = int(request.POST.get(\"num2\"))
return HttpResponse(str(num1+num2))
异步
同步请求指的是当我访问url时,如果在视图函数当中添加一个睡眠,让服务器等待了5秒,
def reg(request):
time.sleep(5)
return render(request,\"reg.html\")
那么相应的,客户端如图所示,也需要等5秒才能进入页面。
但是异步指的是当我在ajax请求的视图函数当中添加一个睡眠,但其他的请求函数不做任何改变的话,那么这个睡眠等待只会影响这一个ajax请求,其他的正常工作。
def check(request):
ret = User.objects.filter(username=request.GET.get(\"name\"))
res = {\"exist\":False, \"msg\":\"\"}
time.sleep(5)
if ret:
res[\"exist\"] = True
res[\"msg\"] = \"该用户已存在\"
return JsonResponse(res)
def add(request):
num1 = int(request.POST.get(\"num1\"))
num2 = int(request.POST.get(\"num2\"))
return HttpResponse(str(num1+num2))
同源策略
之前我们一直输入的是ip地址和端口号以及路由,但是现在直接本地文件的形式打开网页,并且我们代码的路由依然是服务器地址,但是依然会报错。
但问题就是他这个路由请求没有问题,我们可以在后端把1和2都打印出来,但是无法进行响应。
这是因为浏览器
的同源策略导致的
同源策略概念
是一种约定,是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能都会被影响。可以说web是构建在同源策略之上的,浏览器只是针对同源策略的一种实现。
同源策略(same origin policy)是netScape(网景)提出的一个安全策略,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。具体表现为浏览器在执行脚本前,会判断脚本是否与打开的网页是同源的,判断协议、域名、端口是否都相同,相同则表示同源。其中一项不相同就表示跨域访问。会在控制台报一个CORS异常,目的是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
解决方案:跨域资源共享(CORS)
服务端设置,可以允许其他源访问服务端资源,借助nodejs实现。
res = HttpResponse(str(num1+num2))
res[\"Access-Control-Allow-Origin\"] = \"*\"
return res
headers里会有我们添加的那句话,识别到这句话就不会拦截了。
Cors有两种请求,一种是简单请求,一种是非简单请求,只要满足以下两种要求之一就是简单请求
(一)请求方法是下列三个之一:
GET
POST
HEAD
(二) HTTP的头部信息不超过以下几种字段:
- Accept
- Accept-language
- Content-language
- Last-Event-ID
- Content-Type:只限于三个值【application/x-www-form-urlencoded、multipart/form-data、text/plain】
本文来自博客园,作者:ivanlee717,转载请注明原文链接:https://www.cnblogs.com/ivanlee717/p/16849676.html
来源:https://www.cnblogs.com/ivanlee717/p/16849676.html
本站部分图文来源于网络,如有侵权请联系删除。