当前位置: 首页 > news >正文

前端学习记录~2023.8.10~JavaScript重难点实例精讲~第6章 Ajax

第 6 章 Ajax

  • 前言
  • 6.1 Ajax的基本原理及执行过程
    • 6.1.1 XMLHttpRequest对象
      • (1)XMLHttpRequest对象的函数
      • (2)XMLHttpRequest对象的属性
    • 6.1.2 XMLHttpRequest对象生命周期
      • (1)创建XMLHttpRequest对象
      • (2)建立连接
      • (3)发送请求并传递数据
      • (4)处理响应
    • 6.1.3 Ajax的优缺点
      • (1)优点
      • (2)缺点
  • 6.2 使用Nodejs搭建简易服务器
  • 6.3 使用Ajax提交form表单
    • 6.3.1 通用处理
    • 6.3.2 使用原生Ajax进行提交
      • (1)绑定提交按钮事件
      • (2)创建XMLHttpRequet对象
      • (3)建立连接
      • (4)设置请求头
      • (5)获取数据
      • (6)发送请求
      • (7)处理响应
    • 6.3.3 使用jQuery处理Ajax请求进行提交
    • 6.3.4 使用jQuery序列化form表单进行提交
    • 6.3.5 使用FormData对象进行提交
  • 6.4 关于Ajax请求的get方式和post方式
    • 6.4.1 get方式和post方式的区别
    • 6.4.2 使用get方式和post方式需要注意的点
    • 6.4.3 get方式和post方式的使用场景
      • (1)Ajax使用get方式的场景
      • (2)Ajax使用post方式的场景
  • 6.5 Ajax进度事件
    • (1)load事件
    • (2)progress事件
  • 6.6 JSON序列化和反序列化
    • 6.6.1 JSON序列化
      • (1)JSON.stringify()函数
      • (2)自定义toJSON()函数
      • (3)序列化处理的顺序
    • 6.6.2 JSON反序列化
      • (1)JSON.parse()函数
      • (2)eval()函数
  • 6.7 Ajax跨域解决方案
    • 6.7.1 浏览器同源策略
    • 6.7.2 浏览器跨域限制
    • 6.7.3 Ajax跨域请求场景
    • 6.7.4 CORS
    • 6.7.5 JSONP


前言

本章是第六章Ajax相关的内容。

Ajax是一种流行的前后端数据交互的方式,通过异步请求就可以在不需要刷新页面的情况下,达到局部刷新的效果。

Ajax并非是一种全新的技术,而是由以下技术组合而成:

  • 使用CSS和XHTML做页面呈现
  • 使用DOM进行交互和动态显示
  • 使用XMLHttpRequest对象和服务器进行异步通信
  • 使用JavaScript进行绑定和调用,操作DOM

在学完后,希望掌握下面知识点:

  • Ajax的基本原理及执行过程
  • Nodejs搭建简易服务器
  • Ajax提交form表单
  • Ajax进度事件
  • JSON序列化和反序列化
  • Ajax跨域解决方案

6.1 Ajax的基本原理及执行过程

Ajax的基本原理是通过XMLHttpRequest对象向服务器发送异步请求,获取服务器返回的数据后,利用DOM的操作来更新页面。

下面是Ajax的执行流程:
在这里插入图片描述
其中最核心的部分就是XMLHttpRequest对象。它是一个JavaScript对象,支持异步请求,可以及时向服务器发送请求和处理响应,并且不阻塞用户,达到不刷新页面的效果。

下面重点讲解XMLHttpRequest对象相关知识点。

6.1.1 XMLHttpRequest对象

XMLHttpRequest对象从创建到销毁存在一个完整的生命周期,在生命周期的每个阶段会调用XMLHttpRequest对象的不同函数,在函数中需要通过XMLHttpRequest对象的特定属性来判断函数执行情况。

下面就会记录XMLHttpRequest对象的函数和属性

(1)XMLHttpRequest对象的函数

  1. abort():如果请求已经发送,则停止当前请求
  2. getAllResponseHeaders():获取所有HTTP请求的响应头部,作为键值对返回;如果没有收到回应,则返回null
  3. getResponseHeader("key"):获取特定key的HTTP响应头,没有收到响应或不存在则返回null
  4. open("method","URL","[asyncFlag]","[userName]","[password]"):建立对服务器的调用。method表示请求方式,可以为GETPOSTPUT;URL表示请求路径,绝对路径或相对路径均可;后面三个参数可选,表示是否异步、用户名、密码。asyncFlag=true表示异步,false表示同步,默认为true异步
  5. send(content):向服务器发送请求
  6. setRequestHeader("key","value"):设置请求头属性为key的值为value。在设置请求头之前需要先调用open()函数,设置的header将随着send()函数一起发送

(2)XMLHttpRequest对象的属性

  1. onreadystatechange:状态改变的事件触发器。每个状态改变时都会触发这个事件处理器,通常会调用一个JavaScript函数
  2. readyState:请求的状态。有 5 个可取的值:
    • 0:未初始化,XMLHttpRequest对象已创建
    • 1:open()函数已调用,send()函数未调用,请求还未发送
    • 2:send()函数已调用,HTTP请求已发送到服务器,未收到响应
    • 3:所有响应头接收完成,响应体开始接收但未完成
    • 4:HTTP响应接收完成
  3. responseText:接受的数据文本格式的服务器响应体(不包括响应头)
  4. responseXML:服务器的响应,兼容DOM的XML对象,解析后可得到DOM对象
  5. status:服务器返回的HTTP状态码,用数字表示,如200表示成功,404表示资源未找到
  6. statusText:HttP状态码的文本表示,如200时对应"OK",404时对应"Not Found"

6.1.2 XMLHttpRequest对象生命周期

由于浏览器的差异性,创建XMLHttpRequest对象时需要使用不同的方法,主要体现在IE浏览器与其他浏览器之间。

由于现在IE已经基本弃用,因此就不会再记录相关知识。

下面是一个标准的XMLHttpRequest创建方法。

(1)创建XMLHttpRequest对象

function createXMLHttp() {var xmlhttp;// code for IE7+, firefox, chrome, opera, safariif (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();}// code for IE5, IE6 省略return xmlhttp;
}

(2)建立连接

当XMLHttPRequest对象创建完毕后,便可以通过open()函数建立连接,它指定了请求的url地址以及通过url传递的参数;数据传输方式,默认值为true,表示采用异步传输方式

var xhr = createXMLHttp();
xhr.open('post', '/admin/w/saceUser', true);

(3)发送请求并传递数据

在使用open()函数建立连接后,便可以使用send()函数发送请求,并传递数据content。由于传递的数据并不是必须的,所以content值可以为空

var content = {userName:'kingx', password:'123456'};
xhr.send(content);

(4)处理响应

在XMLHttpRequest对象中有一个很重要的onreadystatechange属性,它表示XMLHttpRequest对象状态改变的事件触发器,每次readyState的取值变化时,属性onreadystatechange对应的函数都会被执行一次。
当readyState的值为4时代表响应接收完成,需要注意的是响应接收完成并不代表请求是成功的,我们需要通过HTTP请求status状态码来判断,当status值为200时代表请求成功。
因此在onreadystatechange()回调函数中,我们需要同时判断readyState和status两个值才能对响应值做正确的处理

xhr.onreadystatechange = function(){// 当readyState为4,且状态码为200时代表请求成功if (xhr.readyState === 4 && xhr.status === 200){// 处理响应值document.write(xhr.responseText);}
}

6.1.3 Ajax的优缺点

(1)优点

  • 可以再不刷新页面的情况下更新数据
  • 异步通信
  • 前后端分离
  • 前后端负载分离
  • 标准化支持

(2)缺点

  • 破坏浏览器的正常后退功能
  • 安全性问题
  • 对搜索引擎支持较弱
  • 违背URL唯一资源定位的初衷

6.2 使用Nodejs搭建简易服务器

这块不过多赘述


6.3 使用Ajax提交form表单

form表单默认提交方式会刷新页面,而且会在页面之间进行跳转。
使用Ajax提交form表单就可以在不刷新页面的情况下提交请求,然后在处理响应时通过JavaScript操作DOM,并展示后台处理的信息。

6.3.1 通用处理

使用Ajax提交form表单时,需要对form表单进行特殊处理,包括:

  • 将form标签的action属性和method属性去掉
  • 将提交form表单按钮的type='submit’改为type=‘btton’

下面是一个例子:

<form name="userForm" id="userForm"> <div class="form-group"><label for="username">用户名</label><input type="text" class="form-control" name="username" id="username"> 		</div><div class="form-group"><label for="password">密码</label><input type="password" class="form-control" name="password" id="password"></div><div class="form-group"><label for="telphone">电话</label><input type="text" class="form-control" name="telphone" id="telphone"> </div><div class="form-group"><label for="email">邮箱</label><input type="text" class="form-control" name="email" id="email"></div><div class="text-center"><input type="button" class="btn btn-default btn-primary" value="提交" id="submit"><input type="button" class="btn btn-default" value="取消" id="cancel"> </div>
</form>

效果如下
在这里插入图片描述

6.3.2 使用原生Ajax进行提交

使用原生Ajax提交form表单包含以下过程:

  • 绑定提交按钮事件
  • 创建XMLHttpRequest对象
  • 建立连接
  • 设置请求头
  • 获取数据
  • 发送请求
  • 处理响应

(1)绑定提交按钮事件

在单击提交按钮时触发Ajax请求的操作,将整个Ajax操作封装在ajaxSubmitForm()函数里。按钮获取与事件绑定使用原生的JS语法。

var submitBtn = document.getElementById('submit');
submitBtn.addEventListener('click',function(){ajaxSubmitForm();
})

(2)创建XMLHttpRequet对象

同样是使用6.1.2小节中封装的函数即可

function createXMLHttp() {var xmlhttp;if (window.XMLHttpRequest){xmlhttp = new XMLHttpRequest();}return xmlhttp;
}var xhr = createXMLHttp();

(3)建立连接

本实例可以理解为一个用户的注册操作,发送的请求为POST秦秋,使用异步处理方式

xhr.open('post', '/saveUser', true);

(4)设置请求头

由于本实例中发送的是POST请求,需要设置数据传输格式,即设置Content-type属性值。可以通过setRequestHeader()函数对其进行设置,将其值设置为比较普遍的 JSON数据格式

xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8');

(5)获取数据

通过原生的DOM操作方式获取页面填写的数据

var username = document.getElementById('username').value; 
var password = document.getElementById('password').value;
var telphone = document.getElementById('telphone').value;
var email = document.getElementById('email').value;
var content = {username: username, password: password, telphone: telphone, email: email
};

因为在请求头中设置了数据传输格式为json,所以需要将content对象处理为json字符串

content = JSON.stringify(content);

(6)发送请求

只需要调用send()函数就可以发送请求

xhr.send(content);

(7)处理响应

设置onreadystatechange属性对应的回调函数,在回调函数中进行判断。当响应接收完毕,readyState为4,同时请求状态码status为200时,即表示请求成功,然后就可以编写对应的处理逻辑


xhr.onreadystatechange = function () {// 当readyStatew为4,且状态码为200时代表请求成功 if (xhr.readyState === 4 && xhr.status === 200) {// 处理响应值document.write(xhr.responseText); }
}

在使用原生Ajax提交form表单内容时,需要考虑浏览器兼容性问题,并且该方式的代码冗余度高,需要经常进行状态的判断,因此这并不是一种很好的处理form表单的方式。

6.3.3 使用jQuery处理Ajax请求进行提交

使用jQuery处理Ajax请求,解决了浏览器兼容性的问题,对原生Ajax请求的高度封装也使得代码变得精简。我们只需要关注在使用Ajax时需要什么,然后传递对应的参数,处理不同的回调即可。

但因为也不用,所以不记录了。

6.3.4 使用jQuery序列化form表单进行提交

表单的序列化,表示的是可以自动将表单内填写的内容自动处理为字符串或者对象格式,便于与服务端进行传递,从而避免重复性地通过代码获取单个表单元素输入值。

同样因为不用,不记录了。

6.3.5 使用FormData对象进行提交

FormData对象是HTML5中新增的对象,服务于Ajax请求,用于发送数据。

FormData对象将数据编译成key-value类型的键值对,以便于XMLHttpRequest对象发送数据。其主要用于发送form表单数据,但也可以独立于form表单,发送带有键的数据。

FormData对象提交的最大的优势是可以异步上传文件。

FormData对象的提交既可以支持原生Ajax请求,也可以支持jQuery请求。jQuery就不记录了。

下面记录一下原生Ajax请求使用FormData对象发送form表单数据:
其他部分,例如XMLHttpRequest对象的创建和请求发送,以及请求成功的回调,这里就不做详细描述,我们重点来看FormData对象的使用

(1)请求头设置
使用原生Ajax请求发送带有文件流的FormData数据时,需要对请求头进行对应的设置,即将Content-type属性设置为application/x-www-form-urlencoded

xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

(2)生成FormData实例

var formData = new FormData();

(3)添加数据
通过append()函数向formData对象中添加需要发送的数据,不管是简单的文本类型数据还是文件类型数据,都可以添加到formData对象中

(4)发送数据
调用send()函数传递FormData对象

xhr.send(formData);

6.4 关于Ajax请求的get方式和post方式

Ajax请求通常会有get和post两种方式

6.4.1 get方式和post方式的区别

使用get和post都可以向服务器发送请求,但是发送机制不同:

  • 参数传递
    • get请求:将参数添加到请求URL的后面,没有请求主体,调用send()函数时传递的参数为null,即xhr.send()
    • post请求:会将请求的数据放在请求体中,用户是无法通过URL直接看到的,调用send()函数时传递的参数为data,即xhr.send(data)
  • 服务端参数获取:使用Express作为服务端框架,get请求通过Request.query来获取参数;而使用 post请求时需要添加中间件,同时通过Request.body来获取参数
  • 传递的数据量:get请求传输的数据量小;post请求传递的数据量大
  • 安全性
    • get请求:安全性较低,因为其请求的参数会出现在URL上,而且采用明文进行数据传输,通过浏览器缓存或者历史记录可以很容易获取到某些隐私请求的参数
    • post请求:安全性较高,post请求通过请求体进行数据传输,数据不会出现在URL上,隐藏了请求数据的信息
  • 处理form表单的差异性

6.4.2 使用get方式和post方式需要注意的点

  • 使用get方式请求时,如果请求的url不发生改变,可能会存在缓存的问题,因此在请求的url后一般会拼接上一个时间戳,以避免出现缓存
  • 使用get方式请求时,请求的参数会拼接在url后,如果浏览器编码、服务器编码、数据库编码格式不一致,可能会导致乱码的问题。通常的做法是对请求的参数经过encodeURIComponent()函数处理
xhr.open('get', '/getUser?username='+encodeURIComponent(username), true)
  • 使用post方式请求时,需要设置请求头中的content-type属性,表示数据在发送至服务器时的编码类型。默认情况下,使用post方式提交form表单时,content-type值为application/x-www-form-unlencoded,另外还可以支持multipart/formdata、application/json等格式
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')

6.4.3 get方式和post方式的使用场景

(1)Ajax使用get方式的场景

  • 请求是为了检索资源,form表单的数据仅用于帮助搜索
  • 传递的数据量小,适合于url中传递参数
  • 数据安全性低,适合明文传输

(2)Ajax使用post方式的场景

  • 请求会修改数据库中的资源,例如增删改
  • 传递的数据量大,超出url中携带参数长度的限制
  • 用于用户名、密码及身份证号等类似敏感信息的数据传输

6.5 Ajax进度事件

在之前的内容里,我们有讲到通过监听readystatechange事件,在回调函数中获取readyState和status的值并判断请求是否成功。在XHR2草案中,增加了Ajax请求进度事件Progress Events规范,使得XMLHttpRequest对象能在请求的不同阶段触发不同类型的事件,所以我们可以不再需要判断readyState的属性,也可以处理请求成功和失败的操作。

在Progress Events规范中增加了 7 个进度事件:

  • loadstart:在开始接收响应时触发
  • progress:在接收响应期间不断触发,直至请求完成
  • error:在请求失败时触发
  • abort:在主动调用abort()函数时触发,表示请求终止
  • load:在数据接收完成时触发
  • loadend:在通信完成或者error、abort、load事件后触发
  • timeout:在请求超时时触发

一个完整的ajax请求都会从loadstart事件开始,然后不间断地触发progress事件,然后触发load、abort、timeout或者error事件的其中一个,最后触发loadend事件。

(1)load事件

只要浏览器接收到了服务器的响应,不管其状态如何都会触发load事件。例如,对于状态码为404的请求,仍然会触发load事件,所以在进行请求成功的处理时,需要判断status的值。一般我们判断status值大于等于200且小于300,或者status值等于304时,都是当作请求成功进行处理。

在loadstart、load等事件的回调函数中,都会接收一个event对象,通过event对象的target属性可以获取到XMLHttpRequest对象的实例,因此可以访问到XMLHttpRequest对象的所有属性和函数

(2)progress事件

progress事件会在浏览器接收数据的过程中周期性调用。progress事件处理程序会接收一个event对象,通过它的target属性同样可以获取到XMLHttpRequest对象的实例,而且在event对象中增加了3个有用的属性,分别是lengthComputable、loaded和total

  • lengthComputable:表示进度信息是否可用。是一个布尔值
  • loaded:表示已经接收到的字节数,它的值是根据Content-Length响应头部确定的预期字节数
  • total:表示响应的实际字节数

通过loaded和total属性值可以计算出接收响应的数据百分比,从而实现进度条


6.6 JSON序列化和反序列化

JSON数据在网络传输时存在两种类型,一种是JSON对象类型,一种是JSON字符串类型。两种类型的转换涉及JSON序列化和反序列化的知识。

6.6.1 JSON序列化

JSON序列化即将JSON对象处理为JSON字符串的过程,以方便数据的传输。

有两种方式实现:

  • 调用JSON对象内置的stringify()函数
  • 为对象仔细定义toJSON()函数

(1)JSON.stringify()函数

JSON.stringify(value[,replacer[,space]])
  • value:待处理成JSON字符串的JavaScript值,通常为对象或者数组
  • replacer:是一个可选参数。如果是一个函数,则表示在序列化过程中,被序列化值的每个属性都会经过该函数处理;如果为一个数组,则表示只有包含在这个数组中的属性名才会被序列化到最终JSON字符串中;如果为null或未传递,则value参数对应值的所有属性都会被序列化
  • space:是一个可选参数,用于指定缩进用的空白字符串,美化输出。如果是数字,则代表对应个数空格,上限为10;如果小于1则没有空格;如果为字符串则取字符串的前10个字符作为空格;如果为null或未传入则没有空格

在JSON序列化时,如果属性值为对象或者数组,则会继续序列化该属性值,直到属性值为基本类型、函数或者Symbol类型才结束。

(2)自定义toJSON()函数

如果一个被序列化的对象拥有toJSON()函数,那么toJSON()函数就会覆盖默认的序列化行为,被序列化的值将不再是原来的属性值,而是toJSON()函数的返回值。

toJSON()函数用于更精确的控制序列化,可以看作是对stringify()函数的补充。

(3)序列化处理的顺序

  • 如果待序列化的对象存在toJSON()函数,则优先调用toJSON()函数,以toJSON()函数的返回值作为待序列化的值,否则返回JSON对象本身
  • 如果stringify()函数提供了第二个参数replacer,则对上一步的返回值经过replacer参数处理
  • 如果stringify()函数提供了第三个参数,则对JSON字符串进行格式化处理,返回最终的结果

6.6.2 JSON反序列化

JSON反序列化即将JSON字符串转换为JSON对象的过程,得到的结果用于在JavaScript中做逻辑处理。

有两种方式实现:

  • 使用JSON对象内置的parse()函数
  • 使用eval()函数

(1)JSON.parse()函数

JSON.parse()函数用来解析JSON字符串,构造由字符串描述的JavaScript值或对象

JSON.parse(text[,reviver])
  • text:带解析的JSON字符串
  • reviver:是可选参数。如果是一个函数,则规定了原始值在返回之前如何被解析改造。如果被解析的JSON字符串是非法的,则会抛出异常
JSON.parse('[1,2,3,true]'); // Array [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14} 
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45

当使用JSON.parse()函数解析JSON字符串时,需要注意两点;

  • JSON字符串中的属性名必须用双引号括起来,否则会解析错误
  • JSON字符串不能以逗号结尾,否则会解析异常

(2)eval()函数

eval()函数用于计算JavaScript字符串,并把它作为脚本来执行。

在使用eval()函数进行JSON反序列化时,其语法如下所示:

eval("(" + str + ")")
  • str:待处理的字符串

因为JSON字符串是以{}开始和结束的,在JavaScript中它会被当作一个语句块来处理,所以必须强制将它处理成一个表达式,所以采用括号

var json1 = '{"name":"kingx"}'; 
var json2 = '{"address":["beijing","shanghai"]}'; 
console.log(eval("(" + json1 + ")"));// {name: "kingx"}
console.log(eval("(" + json2 + ")"));// {address: ["beijing", "shanghai"]}

6.7 Ajax跨域解决方案

6.7.1 浏览器同源策略

浏览器同源策略是浏览器最基本也是最核心的安全功能,它约定客户端脚本在没有明确授权的情况下,不能读写不同源的目标资源。

同源明确地表示为相同协议、域名和端口号,如果两个资源路径在协议、域名、端口号上有任何一点不同,则它们就不属于同源的资源。

在同源策略上,又分为 2 种表现形式:

  • DOM同源策略:禁止对不同页面进行DOM操作,主要的场景是iframe跨域,不同域名下的iframe会限制访问
  • XMLHttpRequest同源策略:禁止使用XMLHttpRequest向不是同源的服务器发送Ajax请求

6.7.2 浏览器跨域限制

主要是由没有遵守浏览器的同源策略引起的,浏览器对跨域访问的限制,可以在很大程度上保护用户的隐私数据安全。

下面是两个实际场景

(1)没有DOM同源策略限制

假如浏览器没有DOM同源策略限制,那么不同域的iframe可以相互访问,黑客就可以采用以下的方式发起攻击:

  • 做一个假网站,里面用iframe嵌套一个银行网站
  • 把iframe宽高调整到占据浏览器可视区的全部空间,这样用户在进入网站后,除了域名,其余看到的内容和其他银行网站是一样的
  • 用户在输入用户名和密码后,主网站就可以跨域访问到所嵌套的银行网站的DOM节点,从而黑客就拿到用户输入的用户名和密码了

(2)没有XMLHttpRequest同源策略限制

假如浏览器没有XMLHttpRequest同源策略限制,那么黑客可以进行跨站请求伪造CSRF攻击,具体方式如下:

  • 用户登录了个人银行页面A,页面A会在Cookie中添加用户信息
  • 用户浏览了恶意页面B,在恶意页面中执行了恶意Ajax请求的代码
  • 此时页面B会向页面A发送Ajax请求,该请求会默认发送用户Cookie信息
  • 页面A会从请求的cookie中提取用户信息,验证用户无误,就会返回用户的隐私数据,而此时数据就会被恶意页面B获取到,从而造成用户隐私数据的泄露
  • 由于Ajax请求的发送会自动执行,所以用户是无感知的

6.7.3 Ajax跨域请求场景

虽然浏览器有跨域访问的限制,但是在某些实际的业务场景中,不可避免地需要进行跨域访问。

6.7.4 CORS

CORS(CrossOrigin Resource Sharing,跨域资源共享)。主要实现方式是服务端通过对响应头的设置,接收跨域请求处理。

不同的服务端框架采用的处理方式不同。

通过服务端的处理不会对前端代码做任何修改,但是由于服务端采用的语言、框架多变,处理方式会依赖各种语言的特性。

6.7.5 JSONP

JSONP是客户端与服务器端跨域通信最常用的解决办法,它的特点是简单适用、兼容老式浏览器、对服务器端影响小。

主要思想可以分 2 步理解:

  • 在网页中动态添加一个script标签,通过script标签向服务器发送请求,在请求中会携带一个请求的callback回调函数名
  • 服务器在接收到请求后,会处理响应获取返回的参数,然后将参数放在callback回调函数中对应的位置,并将callback回调函数通过json格式进行返回

构建JSONP请求实际是创建一个新的script元素,通过src属性指定跨域请求的url,并在url中携带请求成功的回调函数作为参数。

回调函数必须设置为全局函数。因为服务端在响应后会从全局查找回调函数,所以如果回调函数不是定义在全局作用域中,那么会报错。

(1)优点

  • 使用简单,不会有兼容性问题,是目前比较流行的跨域解决方案

(2)缺点

  • 只支持get请求,这是JSONP目前最大的缺点。如果是post请求,那么JSONP则无法完成跨域处理
  • 响应依赖于其他域的实现,如果请求的其他域不安全,可能会对本域造成一定的安全性影响
  • 很难确定JSONP请求是否失败,虽然在HTML5中给script标签增加了onerror事件处理程序,但是存在兼容性问题

相关文章:

前端学习记录~2023.8.10~JavaScript重难点实例精讲~第6章 Ajax

第 6 章 Ajax 前言6.1 Ajax的基本原理及执行过程6.1.1 XMLHttpRequest对象&#xff08;1&#xff09;XMLHttpRequest对象的函数&#xff08;2&#xff09;XMLHttpRequest对象的属性 6.1.2 XMLHttpRequest对象生命周期&#xff08;1&#xff09;创建XMLHttpRequest对象&#xff…...

2023年Java核心技术第九篇(篇篇万字精讲)

目录 十七 . 并发相关基础概念 17.1 线程安全 17.2 保证线程安全的两个方法 17.2.1 封装 17.2.2 不可变 17.2.2.1 final 和 immutable解释 17.3 线程安全的基本特性 17.3.1 原子性&#xff08;Atomicity&#xff09; 17.3.2 可见性&#xff08;Visibility&#xff09; 17.3.2.1…...

C#上位机中的单例应用思考

文章目录 一、前言二、上位机单例应用场景2.1 上位机2.2 单例及其应用2.3 上位机中的应用2.3.1 用户登录信息2.3.2 配置文件2.3.3 数据连接池 2.4 一个应用场景的思考 三、总结 一、前言 之前写过一篇关于单例的文——C#中单例模式的实现&#xff0c;讲了讲单例是什么以及在C#…...

Python分享之redis

String 操作 redis中的String在在内存中按照一个name对应一个value来存储 set() #在Redis中设置值&#xff0c;默认不存在则创建&#xff0c;存在则修改 r.set(name, zhangsan) 参数&#xff1a; set(name, value, exNone, pxNone, nxFalse, xxFalse) ex&#xff…...

Linux常用命令——dd命令

在线Linux命令查询工具 dd 复制文件并对原文件的内容进行转换和格式化处理 补充说明 dd命令用于复制文件并对原文件的内容进行转换和格式化处理。dd命令功能很强大的&#xff0c;对于一些比较底层的问题&#xff0c;使用dd命令往往可以得到出人意料的效果。用的比较多的还是…...

DETR-《End-to-End Object Detection with Transformers》论文精读笔记

DETR&#xff08;基于Transformer架构的目标检测方法开山之作&#xff09; End-to-End Object Detection with Transformers 参考&#xff1a;跟着李沐学AI-DETR 论文精读【论文精读】 摘要 在摘要部分作者&#xff0c;主要说明了如下几点&#xff1a; DETR是一个端到端&am…...

网络流量监控-sniffnet

{alert type“info”} 今天来分享一个监控流量的应用sniffnet。 github项目地址&#xff1a;https://github.com/GyulyVGC/sniffnet {/alert} 可以在github的readme上看到这个程序有的特性&#xff1a; 为什么要介绍它呢&#xff1a;主要是多线程、跨平台、可靠、操作简单 我…...

验证go循环删除slice,map的操作和map delete操作不会释放底层内存的问题

目录 切片 for 循环删除切片元素其他循环中删除slice元素的方法方法1方法2&#xff08;推荐&#xff09;方法3 官方提供的方法结论 切片 for 循环删除map元素goalng map delete操作不会释放底层内存go map原理源码CRUD查询新增 操作注意事项map元素是无法取址的map是线程不安全…...

C++二级题2

数字字符求和 #include<iostream> #include<string.h> #include<stdio.h> #include<iomanip> #include<cmath> #include<bits/stdc.h> int a[2000][2000]; int b[2000]; char c[2000]; long long n; using namespace std; int main() {ci…...

DataWhale 机器学习夏令营第三期——任务二:可视化分析

DataWhale 机器学习夏令营第三期 学习记录二 (2023.08.23)——可视化分析1.赛题理解2. 数据可视化分析2.1 用户维度特征分布分析2.2 时间特征分布分析 DataWhale 机器学习夏令营第三期 ——用户新增预测挑战赛 学习记录二 (2023.08.23)——可视化分析 2023.08.17 已跑通baseli…...

ubuntu 上安装flutter dart android studio

因为国内网站不能使用 使用一下&#xff1a; vi ~/.bashrc 最后添加 export FLUTTER_STORAGE_BASE_URLhttps://mirrors.cloud.tencent.com/flutter export PUB_HOSTED_URLhttps://mirrors.tuna.tsinghua.edu.cn/dart-pub export PATH$PATH:/usr/local/go/bin export GOPROXY…...

【Golang】go交叉编译

交叉编译是用来在一个平台上生成另一个平台的可执行程序 。Go 命令集是原生支持交叉编译的。 Mac下编译&#xff1a;Linux 或 Windows 的可执行程序 # linux 可执行程序 CGO_ENABLED0 GOOSlinux GOARCHamd64 go build main.go # Windows可执行程序 CGO_ENABLED0 GOOSwindow…...

【人工智能】—_贝叶斯网络、概率图模型、全局语义、因果链、朴素贝叶斯模型、枚举推理、变量消元

文章目录 频率学派 vs. 贝叶斯学派贝叶斯学派Probability&#xff08;概率&#xff09;:独立性/条件独立性&#xff1a;Probability Theory&#xff08;概率论&#xff09;:Graphical models &#xff08;概率图模型&#xff09;什么是图模型&#xff08;Graphical Models&…...

学习笔记:ROS使用经验( 查看rostopic的信息)

查看topic的信息 要查看ROS中的话题信息&#xff0c;你可以使用以下命令&#xff1a; 1.查看所有活动话题&#xff1a; $ rostopic list这将列出当前运行的所有活动话题。 2.查看特定话题的消息类型&#xff1a; $ rostopic info <topic_name>将<topic_name>替…...

数据库——redis内存淘汰,持久化机制

文章目录 Redis 内存淘汰机制了解么&#xff1f;⭐了解操作系统中lru并尝试用java实现lru 2.Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复)快照&#xff08;snapshotting&#xff09;持久化&#xff08;RDB&#xff09;AOF&#xff08;append-only file&am…...

亚马逊云科技 云技能孵化营 我也说ai

自从chatgpt大火以后&#xff0c;我也关注了人工智能方面的东西&#xff0c;偶尔同学推荐参加了亚马逊云科技云技能孵化营活动&#xff0c;免费学习了亚马逊云科技和机器学习方面的知识&#xff0c;还获得了小礼品&#xff0c;现在将活动及心得分享给大家。 活动内容&#xff…...

『PyQt5-基础篇』| 04 Qt Designer的初步快速了解

04 Qt Designer的初步快速了解 1 Qt Designer入口2 Qt Designer-Widget Box2.1 窗口部件盒(Widget Box)2.2 Layouts布局2.3 Spacers间隔部件2.4 Button按钮2.5 Item Views(Model-Based)2.6 Item Widgets(Item-Based)2.7 Containers容器2.8 Input Widget输入部件2.9 Display W…...

SpringCloud学习笔记(十一)_Hystrix仪表盘

我们来看一下如何使用它吧 1.引入依赖 1 2 3 4 5 6 7 8 9 10 11 12 | <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </depende…...

# ruby安装设置笔记

ruby安装设置笔记 文章目录 ruby安装设置笔记1 克隆并设置环境变量2 安装ruby3 设置ruby4 设置源5 安装bundler6 检查安装后的软件版本7 ubuntu 20.04 默认ruby环境 系统自带的ruby版本低了&#xff0c;需要手动安装更高版本&#xff08;使用rbenv方式&#xff09; 环境&#x…...

关于对文件路径权限判断的记录

首先需要添加引用 using System.Security.AccessControl;以下为具体代码&#xff0c;其中fileServerPath为需要判断的文件路径 #region Authority judgmentDirectorySecurity fileAcl Directory.GetAccessControl(fileServerPath);var rules fileAcl.GetAccessRules(true, t…...

git 基础

1.下载安装Git&#xff08;略&#xff09; 2.打开git bash窗口 3.查看版本号、设置用户名和邮箱 用户名和邮箱可以随意起&#xff0c;与GitHub的账号邮箱没有关系 4.初始化git 在D盘中新建gitspace文件夹&#xff0c;并在该目录下打开git bash窗口 git init 初始化完成后会…...

C语言网络编程实现广播

1.概念 如果同时发给局域网中的所有主机&#xff0c;称为广播 我们可以使用命令查看我们Linux下当前的广播地址&#xff1a;ifconfig 2.广播地址 以192.168.1.0 (255.255.255.0) 网段为例&#xff0c;最大的主机地址192.168.1.255代表该网段的广播地址&#xff08;具体以ifcon…...

js对url进行编码解码(三种方式)

第一种&#xff1a;escape 和 unescape escape()不能直接用于URL编码&#xff0c;它的真正作用是返回一个字符的Unicode编码值 它的具体规则是&#xff0c;除了ASCII字母、数字、标点符号" * _ - . /"以外&#xff0c;对其他所有字符进行编码。在u0000到u00ff之间…...

React面向组件编程

往期回顾&#xff1a;# React基础入门之虚拟Dom【一】 面向组件编程 react是面向组件编程的一种模式&#xff0c;它包含两种组件类型&#xff1a;函数式组件及类式组件 函数式组件 注&#xff1a;react17开始&#xff0c;函数式组件成为主流 一个基本的函数组件长这个样子 …...

Linux 多线程同步机制(上)

文章目录 前言一、线程同步二、互斥量 mutex三、死锁总结 前言 一、线程同步 在多线程环境下&#xff0c;多个线程可以并发地执行&#xff0c;访问共享资源&#xff08;如内存变量、文件、网络连接 等&#xff09;。 这可能导致 数据不一致性, 死锁, 竞争条件等 问题。 为了解…...

C++学习vector

1,把list的相关函数都实现出来&#xff08;未完&#xff09; 2&#xff0c; 运行结果&#xff1a;...

17.3 【Linux】systemctl 针对 service 类型的配置文件

17.3.1 systemctl 配置文件相关目录简介 服务的管理是通过 systemd&#xff0c;而 systemd 的配置文件大部分放置于/usr/lib/systemd/system/ 目录内。但是 Red Hat 官方文件指出&#xff0c; 该目录的文件主要是原本软件所提供的设置&#xff0c;建议不要修改&#xff01;而要…...

融云获评「创业邦 · 最具创新价值出海服务商」

点击报名&#xff0c;9 月 21 日融云直播课 8 月 22 日 - 23 日&#xff0c;创业邦主办的“2023 DEMO WORLD 全球开放式创新大会暨企业出海未来大会”在上海举行&#xff0c;会上发布了“创业邦 2023 出海企业创新价值 100 强”&#xff0c;融云荣登榜单&#xff0c;获评“最具…...

【中危】Apache XML Graphics Batik<1.17 存在SSRF漏洞 (CVE-2022-44729)

zhi.oscs1024.com​​​​​ 漏洞类型SSRF发现时间2023-08-23漏洞等级中危MPS编号MPS-2022-63578CVE编号CVE-2022-44729漏洞影响广度极小 漏洞危害 OSCS 描述Apache XML Graphics Batik 是一个开源的、用于处理可缩放矢量图形(SVG)格式图像的工具库。 受影响版本中&#xff0…...

AssemblyManager 程序集管理器

AssemblyManager 程序集管理器 程序执行中使用反射对框架的搭建有着强大的影响&#xff0c;如何管理程序集方便使用反射获取类型操作对象是本文章的重点 1.AssemblyInfo 对于一个程序集这里使用一个AssemblyInfo对象进行管理 Assembly &#xff1a;对应的程序集AssemblyTyp…...

几个nlp的小任务(生成式任务——语言模型(CLM与MLM))

@TOC 本章节需要用到的类库 微调任意Transformers模型(CLM因果语言模型、MLM遮蔽语言模型) CLM MLM 准备数据集 展示几个数据的结构...

单元测试用例mock的使用方法

单元测试用例mock的使用方法 提升代码测试覆盖率的关键策略 为什么单元测试是如此重要&#xff1f; 在软件开发中&#xff0c;单元测试是一个关键的环节&#xff0c;可以确保代码的质量和稳定性。而在进行单元测试时&#xff0c;使用mock对象可以帮助我们更好地测试代码逻辑…...

3D步进式漫游能够在哪些行业应用?

VR技术一直以来都是宣传展示领域中的热门话题&#xff0c;在VR全景技术的不断发展下&#xff0c;3D步进式漫游技术也逐渐覆盖各行各业&#xff0c;特别是在建筑、房产、博物馆、企业等领域应用更加广泛&#xff0c;用户通过这种技术能够获得更加直观、生动、详细的展示体验&…...

2023蓝帽杯初赛ctf部分题目

Web LovePHP 打开网站环境&#xff0c;发现显示出源码 来可以看到php版本是7.4.33 简单分析了下&#xff0c;主要是道反序列化的题其中发现get传入的参数里有_号是非法字符&#xff0c;如果直接传值传入my_secret.flag&#xff0c;会被php处理掉 绕过 _ 的方法 对于__可以…...

vue3+ts封装弹窗,分页封装

定义defaultDialog .vue <script lang"ts" setup> import { ref,toRefs,onUpdated } from vue import { ElMessageBox } from element-plus const props defineProps({//接收参数&#xff0c;父组件传的时候用:msg123的形式msg:String,show:{type:Boolean,defa…...

2023-08-30 数据库-并发控制-冲突可串行化调度-是否可串行化检测-优先图-分析

摘要: 将冲突进行可串行化调度, 是解决冲突是一个基本功能. 对于冲突是否可被串行化调度, 比较有效的就是优先图的方法. 本文对检测冲突可串行化调度的优先图做一些分析. 上下文参考: 2023-08-30 数据库-并发控制-冲突可串行化的调度-思考_财阀悟世的博客-CSDN博客 事务的基…...

人员着装识别算法 yolo

人员着装识别系统通过yolo网络模型识别算法&#xff0c;人员着装识别系统算法通过现场安装的摄像头识别工厂人员及工地人员是否按要求穿戴着装&#xff0c;实时监测人员的着装情况&#xff0c;并进行相关预警。目标检测架构分为两种&#xff0c;一种是two-stage&#xff0c;一种…...

Linux:权限

目录 一、shell运行原理 二、权限 1.权限的概念 2.文件访问权限的相关设置方法 三、常见的权限问题 1.目录权限 2.umsk(权限掩码) 3.粘滞位 一、shell运行原理 1.为什么我们不是直接访问操作系统&#xff1f; ”人“不善于直接使用操作系统如果让人直接访问操作系统&a…...

Unity记录4.3-存储-点击Tilemap保存或读取区块

文章首发见博客&#xff1a;https://mwhls.top/4816.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议&#xff0c;私信不回。 汇总&#xff1a;Unity 记录 摘要&#xff1a;点击tilemap&#xff0c;文件 保存/读取 该地图区块数据…...

【小吉测评】哔哩哔哩接入AI?!效果如何?

文章目录 &#x1f384;前言⭐申请方式&#x1f3f3;️‍&#x1f308;注意 &#x1f6f8;简介&#x1f354;上手体验&#x1f6f8;进行数学计算&#x1f970;可以写代码吗 &#x1f384;前言 最近人工智能特别火&#xff0c;chatgpt&#xff0c;Claude2&#xff0c;文心一言等…...

微信开发之一键踢出群聊的技术实现

简要描述&#xff1a; 删除群成员 请求URL&#xff1a; http://域名地址/deleteChatRoomMember 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选…...

基于Spring Boot 的 Ext JS 应用框架之coworkee

Ext JS 官方提供了一个人员管理的完整应用框架 - coworkee。该框架的显示如下: 该框架的布局特点如下: 布局方式: 左右布局, 左侧导航栏默认收合特点:左侧导航区占用空间小, 工作区较大, 适合没有二级导航栏,工作区需要显示的内容较多的系统。如果导航栏是横向底部,就…...

HOT100打卡—day10—【DP+多维DP】—最新8.29(剩6题)

DP 1 70. 爬楼梯 70. 爬楼梯 一次做&#xff0c;AC代码&#xff1a; 疑问&#xff1a;怎么判断用搜索还是dp&#xff1f;这题&#xff0c;我没有受过dp训练所以第一反应是用dfs搜索&#xff0c;找到所有符合要求的叶子。 class Solution { public:int dp[50]; // step1&a…...

【不会用这个工具,你的Linux服务器就是个摆设!】

01 Tcpdump Tcpdump 是一个强大的网络监控工具&#xff0c;它允许用户有效地过滤网络上的数据包和流量。 这可以获得有关 TCP/IP 和网络上传输的数据包的详细信息。 当你遇到网络协议问题一筹莫展的时候&#xff0c;这时候往往可以通过tcpdump来看网络的通讯过程中发生了什么…...

09 生产者分区机制

kafka如何保证消息的有序 可以通过key-ording策略解决。kafka可以为每条消息定义消息键&#xff0c;也称为key&#xff0c;通常是带有业务属性的比如用户id之类的。有相同消息键的消息会被发到同一个分区。下面实现了key-ordering策略&#xff0c;对key的hashcode进行取模来决…...

亚马逊鲲鹏系统是怎么操作测评的

亚马逊鲲鹏系统可以注册亚马逊买家号、养号、下单留评等&#xff0c;是一款功能比较齐全的测评软件&#xff0c;具体操作如下&#xff1a; 首先我们需要先准备好买家账号&#xff0c;账号可以直接去购买已经注册好了的账号&#xff0c;也可以准备好账号所需要的一些邮箱、ip、…...

电脑上的视频如何导入苹果手机?

AirDroid支持Windows、macOS、android、iOS相互传输文件、视频、图片等。 想要从电脑传输文件到iPhone也很简单&#xff0c;在电脑和iPhone都安装AirDroid&#xff0c;连接同一网络&#xff0c;然后登录同一个帐号就可以了。可绑定的iPhone数量不限&#xff0c;只要都登录同一…...

tsmc standard cell命名规则

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 CKMUX2代表二输入clock mux&#xff0c;D2代表驱动强度X2&#xff0c;6T代表row高为6track&#xff0c;16P96C代表gate length和poly pitch&#xff0c;LVT就是low voltage thr…...

基于ssm医院在线挂号预约系统源码和论文

基于ssm医院在线挂号预约系统源码和论文072 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 课题研究的目的及意义&#xff1a; 专家号难求&#xff0c;是医院现场挂号存在的主要问题之一&#xff0c;每一名专…...

mysql binlog 浅谈

如何开启MySQL的binlog日志 在MySQL中&#xff0c;binlog指的是binary log&#xff0c;二进制日志文件。这个文件记录了MySQL所有的DML操作。通过binlog日志&#xff0c;我们可以做数据恢复&#xff0c;做主从复制等等。对于运维或架构人员来说&#xff0c;开启binlog日志功能…...