ajax的请求,异步,同源策略的学习

Ajax

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指⼀种创建交互式⽹⻚应⽤的⽹⻚开发技术。

Ajax 是⼀种⽤于创建快速动态⽹⻚的技术。

Ajax 是⼀种在⽆需重新加载整个⽹⻚的情况下,能够更新部分⽹⻚的技术。

通过在后台与服务器进⾏少量数据交换,Ajax 可以使⽹⻚实现异步更新。这意味着可以在不重新加载整个⽹⻚的情况下,对⽹⻚的某部分进⾏更新。

传统的⽹⻚(不使⽤ Ajax)如果需要更新内容,必须重载整个⽹⻚⻚⾯。

Ajax的优点:

异步:发送⼀个请求,不需要等待响应返回,随时可以再发送下⼀个请求,即不需要等待。

局部刷新:通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。【传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。】

应用场景:

image-20221027114444300这是一个cnblog账户注册界面,当我们在填写昵称的时候输入regina,这个过程本身并没有进行表单提交或者向服务器发送请求,但是当光标离开这个input框之后,就会自动检测了这里面的内容,并且返回提示这个昵称被占用了,而在图二到图三的过程当中,前端显示为下图,有一个刷新的过程,这个就是由于Ajax的局部刷新作用

image-20221027114424672

这个过程中到底浏览器做了些什么工作

image-20221027130522590

我们筛选出XHR(XmlHttpResponse)类型的报文,看到其实浏览器是进行了一个checkDisplayName的操作发送给了服务器,然后服务器的返回如下

image-20221027130705026

image-20221027131118350

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请求

image-20221031163348141

首先确定一个概念就是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>
密码&nbsp;&nbsp;&nbsp;&nbsp;<input type="password"><br>
<input type="submit">

<script>
    $(".user").blur(function () {
        alert(123);
    })
</script>
</body>
</html>

首先做一个测试,当光标移除用户名时,会弹窗。

image-20221031164212951

现在改为ajax请求的方式

<script>
    $(".user").blur(function () {
        $.ajax({
            url:"http://127.0.0.1:8001/user/check/",
            //请求方式默认get
        })
    })
</script>

然后我们设置好路由,在用户名中输入内容并离开框,看是否有新的请求发出。

image-20221031165343058

我们的目的是要将input标签里的用户名传给后端

$(".user").blur(function () {
        $.ajax({
            url:"http://127.0.0.1:8001/user/check/",
            //请求方式默认get
            data:{
                "name" : $(".user").val()
            },
        })
    })

image-20221031170310550

经过测试,我们的数据已经传回给了后端,并且也可以打印出来,现在要做的就是进行一个验证再反馈到前端

def check(request):
    ret = User.objects.filter(username=request.GET.get("name"))
    if ret:
        return HttpResponse("用户已存在")
    else:
        return HttpResponse("")

image-20221031170719397

image-20221031170736348

这样的话请求我们就做好了

$.ajax({
            url:"http://127.0.0.1:8001/user/check/",
            //请求方式默认get
            data:{
                "name" : $(".user").val()
            },
            //当相响应正常时触发当函数
            success:function (res) {
                console.log(res)
            }           
        })

image-20221031171045159

success参数得到了后端响应回来的数据,并打印了出来,现在可以通过dom对象的操作,将返回内容添加到登陆界面进行提示。在用户名标签的后面添加一个span标签,然后选中标签进行添加内容

$(".err").html(res)

image-20221031171612764

image-20221031171653871

响应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(" ");
  }

image-20221031203024224这样我们也可以拿到序列化中的值,但是ajax好的一点就是当我们用JsonResponse(res),在html中我们可以直接调用参数,不需要再进行parse反序列化。

image-20221031203409233

练习实例

用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))

image-20221031205211605

异步

同步请求指的是当我访问url时,如果在视图函数当中添加一个睡眠,让服务器等待了5秒,

def reg(request):
    time.sleep(5)
    return render(request,"reg.html")

image-20221031210232136

那么相应的,客户端如图所示,也需要等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))

image-20221031210539763

同源策略

image-20221101235237131

之前我们一直输入的是ip地址和端口号以及路由,但是现在直接本地文件的形式打开网页,并且我们代码的路由依然是服务器地址,但是依然会报错。

image-20221101235353713

但问题就是他这个路由请求没有问题,我们可以在后端把1和2都打印出来,但是无法进行响应。

image-20221101235440265

image-20221101235548220

这是因为浏览器的同源策略导致的

同源策略概念

是一种约定,是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能都会被影响。可以说web是构建在同源策略之上的,浏览器只是针对同源策略的一种实现。

同源策略(same origin policy)是netScape(网景)提出的一个安全策略,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。具体表现为浏览器在执行脚本前,会判断脚本是否与打开的网页是同源的,判断协议、域名、端口是否都相同,相同则表示同源。其中一项不相同就表示跨域访问。会在控制台报一个CORS异常,目的是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

image-20221102000002541

解决方案:跨域资源共享(CORS)

服务端设置,可以允许其他源访问服务端资源,借助nodejs实现。

res = HttpResponse(str(num1+num2))
res["Access-Control-Allow-Origin"] = "*"
return res

image-20221102000718600

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】

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ajax的请求,异步,同源策略的学习 - Python技术站

(0)
上一篇 2023年4月2日 下午4:35
下一篇 2023年4月2日

相关文章

  • mysql面试小结

    MySQL 1. 索引 1.1 什么是索引 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。 索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。 更通俗的说,索引就相当于目录。为了方便查找书中的内容,…

    MySQL 2023年4月18日
    00
  • Django_渲染详解

    Django_render 模板语法 模板引擎是一种可以让开发者把服务端数据填充到html网页中完成渲染效果的技术。它实现了把前端代码和服务端代码分离的作用,让项目中的业务逻辑代码和数据表现代码分离,让前端开发者和服务端开发者可以更好的完成协同开发。 静态网页:页面上的数据都是写死的,万年不变 动态网页:页面上的数据是从后端动态获取的(比如后端获取当前时间;…

    2023年4月2日
    00
  • 数据分析之pandas的使用

    pandas 为什么学习pandas numpy已经可以帮助我们进行数据的处理了,那么学习pandas的目的是什么呢? numpy能够帮助我们处理的是数值型的数据,当然在数据分析中除了数值型的数据还有好多其他类型的数据(字符串,时间序列),那么pandas就可以帮我们很好的处理除了数值型的其他数据! 什么是pandas? 首先先来认识pandas中的两个常用…

    2023年4月2日
    00
  • pandas替换,加载,透视表

    pandas的级联和合并 级联操作 pd.concat, pd.append pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数: objs axis=0 keys join=’outer’ / ‘inner’:表示的是级联的方式,outer会将所有的项进行级联(忽略匹配和不匹配),而inner只会将匹配的项级联…

    2023年4月2日
    00
  • linux文件权限解读

    Linux 文件权限 文件权限和文件类型共有10个字符组成,这10个字符可以分成三部分 \[d+rwx+rwx+rw-\\d:表示文件类型\\2-4位(第一组rwx):表示文件所有者的对文件的权限\\5-7位(第二组rwx):表示文件所有者所在组的用户对文件的权限\\8-10位(rw-):表示其他用户对文件的权限 \] 其中 r 表示可读,w 表示可写,x …

    Linux 2023年4月18日
    00
  • phpt文件内容解析

    phpt测试文件说明 phpt文件用于PHP的自动化测试,这是PHP用自己来测试自己的测试数据用例文件。 测试脚本通过执行PHP源码根目录下的run-tests.php,读取phpt文件执行测试。 phpt文件包含 TEST,FILE,EXPECT 等多个段落的文件。在各个段落中,TEST、FILE、EXPECT是基本的段落, 每个测试脚本都必须至少包括这三…

    PHP 2023年4月19日
    00
  • django学习_路由

    django2 路由控制器 Route路由,是一种映射关系。路由是把客户端请求的url路径和用户请求的应用程序,这里意指django里面的视图进行绑定映射的一种关系。 请求路径和视图函数不是一一对应的关系 在django中所有的路由最终都被保存到一个叫urlpatterns的文件里,并且该文件必须在主应用下的urls.py里进行声明,这是由setting文件…

    2023年4月2日
    00
  • django学习__1

    Django python网络编程回顾 之前我们介绍过web应用程序和http协议,简单了解过web开发的概念。Web应用程序的本质 接收并解析HTTP请求,获取具体的请求信息 处理本次HTTP请求,即完成本次请求的业务逻辑处理 构造并返回处理结果——HTTP响应 import socket server = socket.socket() server.b…

    Python开发 2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部