草庐IT

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

WELCOME TO ivanlee717!!!! 2023-04-16 原文

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>
密码&nbsp;&nbsp;&nbsp;&nbsp;<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】

有关ajax的请求,异步,同源策略的学习的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  6. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  7. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  8. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐