【JavaScript 漫游】【034】AJAX

魔幻都市

文章简介

本篇文章为【JavaScript 漫游】专栏的第 034 篇文章,对浏览器模型的 XMLHttpRequest 对象(AJAX)的知识点进行了总结。

XMLHttpRequest 对象概述

浏览器与服务器之间,采用 HTTP 协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出 HTTP 请求。

1999年,微软公司发布 IE 浏览器5.0版,第一次引入新功能:允许 JavaScript 脚本向服务器发起 HTTP 请求。这个功能当时并没有引起注意,直到2004年 Gmail 发布和2005年 Google Map 发布,才引起广泛重视。2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。W3C 也在2006年发布了它的国际标准。

具体来说,AJAX 包括以下几个步骤。

  1. 创建 XMLHttpRequest 实例
  2. 发出 HTTP 请求
  3. 接收服务器传回的数据
  4. 更新网页数据

概括起来,就是一句话,AJAX 通过原生的 XMLHttpRequest 对象发出 HTTP 请求,得到服务器返回的数据后,再进行处理。现在,服务器返回的都是 JSON 格式的数据,XML 格式已经过时了,但是 AJAX 这个名字已经成了一个通用名词,字面含义已经消失了。

XMLHttpRequest 对象是 AJAX 的主要接口,用于浏览器与服务器之间的通信。尽管名字里面有 XMLHttp ,它实际上可以使用多种协议(比如 fileftp),发送任何格式的数据(包括字符串和二进制)。

XMLHttpRequest 本身是一个构造函数,可以使用 new 命令生成实例。它没有任何参数。

var xhr = new XMLHttpRequest();

一旦新建实例,就可以使用 open() 方法指定建立 HTTP 连接的一些细节。

xhr.open('GET', 'http://www.example.com/page.php', true);

第一个参数指定方法类型,第二个参数指定服务器网址,第三个参数表示是否为异步。

然后,指定回调函数,监听通信状态(readyState 属性)的变化。

xhr.onreadystatechange = handleStateChange;function handleStateChange() {// ...
}

一旦 XMLHttpRequest 实例的状态发生变化,就会调用监听函数 handleStateChange

最后使用 send() 方法,实际发出请求。

xhr.send(null);

send() 的参数为 null,表示发送请求的时候,不带有数据体。如果发送的是 POST 请求,这里就需要指定数据体。

一旦拿到服务器返回的数据,AJAX 不会刷新整个网页,而是只更新网页里面的相关部分,从而不打断用户正在做的事情。

注意,AJAX 只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错。

var xhr = new XMLHttpRequest();xhr.onreadystatechange = function() {// 通信成功时,状态值为 4if (xhr.readyState === 4) {if (xhr.status === 200) {console.log(xhr.responseText);} else {console.log(xhr.statusText);}}
};xhr.onerror = function (e) {console.log(xhr.statusText);
};xhr.open('GET', '/endpoint', true);
xhr.send(null);

XMLHttpRequest 的实例属性

readyState

返回一个整数,表示实例对象的当前状态,只读,可能返回以下值。

  • 0,表示 XMLHttpRequest 实例已经生成,但是实例的 opne() 还没有被调用
  • 1,表示 open() 方法已经被调用,但是实例的 sned() 还没有调用,仍然可以使用实例的 setRequestHeader(),设定 HTTP 请求的头信息
  • 2,表示实例的 send() 方法已经调用,并且服务器返回的头信息和状态码已经收到
  • 3,表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的 responseType 属性等于 text 或者空字符串,responseText 属性就会包含已经收到的部分信息
  • 4,表示服务器返回的数据已经完全接收,或者本次接收已经失败

通信过程中,每当实例对象发生状态变化,它的 readyState 属性的值就会改变。这个值每一次变化,都会触发 readyStateChange 事件。

var xhr = new XMLHttpRequest();if (xhr.readyState === 4) {// 请求结束,处理服务器返回的数据
} else {// 显示提示“加载中……”
}

onreadystatechange

指向一个监听函数,readystatechange 事件发生时(实例的 readyState 属性变化),就会执行这个属性。

另外,如果使用实例的 abort(),终止 XMLHttpRequest 请求,也会造成 readyState 属性变化,导致调用 XMLHttpRequest.onreadystatechange 属性。

var xhr = new XMLHttpRequest();
xhr.open( 'GET', 'http://example.com' , true );
xhr.onreadystatechange = function () {if (xhr.readyState !== 4 || xhr.status !== 200) {return;}console.log(xhr.responseText);
};
xhr.send();

response

服务器返回的数据体(即 HTTP 响应的 body 部分)。它可能是任何数据类型,比如字符串、对象、二进制对象等等,具体的类型由 XMLHttpRequest.responseType 属性决定。该属性只读。

如果本次请求没有成功或者数据不完整,该属性等于 null。但是,如果 responseType 属性等于 text 或空字符串,在请求没有结束之前(readyState 等于 3 的阶段),response 属性包含服务器已经返回的部分数据。

var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState === 4) {handler(xhr.response);}
}

responseType

服务器返回数据的类型。这个属性可写,可以在调用 open() 之后、send() 之前,设置这个属性的值,告诉服务器返回指定类型的数据。如果 responseType 设为空字符串,就等同于默认值 text

XMLHttpRequest.responseType 属性可以等于以下值。

  • “”(空字符串):等同于 text,表示服务器返回文本数据
  • “arrarybuffer”:ArrayBuffer 对象,表示服务器返回二进制数组
  • “blob”:Blob 对象,表示服务器返回二进制对象
  • “document”:Document 对象,表示服务器返回一个文档对象
  • “json”:JSON 对象
  • “text”:字符串

上面几种类型之中,text 类型适合大多数情况,而且直接处理文本也比较方便。document 类型适合返回 HTML / XML 文档的情况,这意味着,对于那些打开 CORS 的网站,可以直接用 Ajax 抓取网页,然后不用解析 HTML 字符串,直接对抓取回来的数据进行 DOM 操作。blob 类型适合读取二进制数据,比如图片文件。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';xhr.onload = function(e) {if (this.status === 200) {var blob = new Blob([xhr.response], {type: 'image/png'});// 或者var blob = xhr.response;}
};xhr.send();

如果将这个属性设为 ArrayBuffer,就可以按照数组的方式处理二进制数据。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';xhr.onload = function(e) {var uInt8Array = new Uint8Array(this.response);for (var i = 0, len = uInt8Array.length; i < len; ++i) {// var byte = uInt8Array[i];}
};xhr.send();

如果将这个属性设为 json,浏览器就会自动对返回数据调用 JSON.parse() 方法。也就是说,从 xhr.response 属性(注意,不是 xhr.responseText 属性)得到的不是文本,而是一个 JSON 对象。

responseText

从服务器接收到的字符串,该属性为只读,只有 HTTP 请求完成接收以后,该属性才会包含完整的数据。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);xhr.responseType = 'text';
xhr.onload = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log(xhr.responseText);}
};xhr.send(null);

responseXML

返回从服务器接收到的 HTML 或 XML 文档对象,只读。如果本次请求没有成功,或者收到的数据不能被解析为 XML 或 HTML,该属性等于 null

该属性生效的前提是 HTTP 响应的 Content-Type 头信息等于 text/xmlapplication/xml。这要求在发送请求前,XMLHttpRequest.responseType 属性要设为 document。如果 HTTP 响应的 Content-Type 头信息不等于 text/xmlapplication/xml,但是从 responseXML 拿到数据(即把数据按照 DOM 格式解析),那么需要手动调用 XMLHttpRequest.overrideMimeType(),强制进行 XML 解析。

该属性得到的数据,是直接解析后的文档 DOM 树。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);xhr.responseType = 'document';
xhr.overrideMimeType('text/xml');xhr.onload = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log(xhr.responseXML);}
};xhr.send(null);

responseURL

发送数据的服务器的网址。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/test', true);
xhr.onload = function () {// 返回 http://example.com/testconsole.log(xhr.responseURL);
};
xhr.send(null);

注意,这个属性的值与 open() 指定的请求网址不一定相同。如果服务器端发生跳转,这个属性返回最后实际返回数据的网址。另外,如果原始 URL 包括锚点(fragment),该属性会把锚点剥离。

statusstatusText

status 返回一个整数,表示服务器回应的 HTTP 状态码。一般来说,如果通信成功的话,这个状态码是 200;如果服务器没有返回状态码,那么这个属性默认是 200。请求发出之前,该属性为 0。该属性只读。

  • 200,OK,访问正常
  • 301,Moved Permanently,永久移动
  • 302,Moved temporarily,暂时移动
  • 304,Not Modified,未修改
  • 307,Temporary Redirect,暂时重定向
  • 401,Unauthorized,未授权
  • 403,Forbidden,禁止访问
  • 404,Not Found,未发现指定网址
  • 500,Internet Server Error,服务器发生错误

基本上,只有 2xx 和 304 的状态码,表示服务器返回是正常状态。

if (xhr.readyState === 4) {if ( (xhr.status >= 200 && xhr.status < 300)|| (xhr.status === 304) ) {// 处理服务器的返回数据} else {// 出错}
}

statusText 属性返回一个字符串,表示服务器发送的状态提示。不同于 status 属性,该属性包含整个状态信息,比如 “OK” 和 “Not Found”。在请求发送之前(即调用 open() 之前),该属性的值是空字符串;如果服务器没有返回状态提示,该属性的值默认为“OK”。该属性为只读属性。

timeoutontimeout

timeout 返回一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。如果该属性等于 0,就表示没有时间限制。

ontimeout 属性用于设置一个监听函数,如果发生 timeout 事件,就会执行这个监听函数。

var xhr = new XMLHttpRequest();
var url = '/server';xhr.ontimeout = function () {console.error('The request for ' + url + ' timed out.');
};xhr.onload = function() {if (xhr.readyState === 4) {if (xhr.status === 200) {// 处理服务器返回的数据} else {console.error(xhr.statusText);}}
};xhr.open('GET', url, true);
// 指定 10 秒钟超时
xhr.timeout = 10 * 1000;
xhr.send(null);

事件监听属性

XMLHttpRequest 对象可以对以下事件指定监听函数。

  • XMLHttpRequest.onloadstart:loadstart 事件(HTTP 请求发出)的监听函数
  • XMLHttpRequest.onprogress:progress事件(正在发送和加载数据)的监听函数
  • XMLHttpRequest.onabort:abort 事件(请求中止,比如用户调用了abort()方法)的监听函数
  • XMLHttpRequest.onerror:error 事件(请求失败)的监听函数
  • XMLHttpRequest.onload:load 事件(请求成功完成)的监听函数
  • XMLHttpRequest.ontimeout:timeout 事件(用户指定的时限超过了,请求还未完成)的监听函数
  • XMLHttpRequest.onloadend:loadend 事件(请求完成,不管成功或失败)的监听函数
xhr.onload = function() {var responseText = xhr.responseText;console.log(responseText);// process the response.
};xhr.onabort = function () {console.log('The request was aborted');
};xhr.onprogress = function (event) {console.log(event.loaded);console.log(event.total);
};xhr.onerror = function() {console.log('There was an error!');
};

progress 事件的监听函数有一个事件对象参数,该对象有三个属性:loaded 属性返回已经传输的数据量,total 属性返回总的数据量,lengthComputable 属性返回一个布尔值,表示加载的进度是否可以计算。所有这些监听函数里面,只有 progress 事件的监听函数有参数,其他函数都没有参数。

注意,如果发生网络错误(比如服务器无法连通),onerror 事件无法获取报错信息。也就是说,可能没有错误对象,所以这样只能显示报错的提示。

withCredentials

表示跨域请求时,用户信息(比如 Cookie 和认证的 HTTP 头信息)是否会包含在请求之中,默认为false,即向 example.com 发出跨域请求时,不会发送 example.com 设置在本机上的 Cookie(如果有的话)。

如果需要跨域 AJAX 请求发送 Cookie,需要 withCredentials 属性设为 true。注意,同源的请求不需要设置这个属性。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);

为了让这个属性生效,服务器必须显式返回 Access-Control-Allow-Credentials 这个头信息。

Access-Control-Allow-Credentials: true

withCredentials 属性打开的话,跨域请求不仅会发送 Cookie,还会设置远程主机指定的 Cookie。反之也成立,如果 withCredentials 属性没有打开,那么跨域的 AJAX 请求即使明确要求浏览器设置 Cookie,浏览器也会忽略。

注意,脚本总是遵守同源政策,无法从 document.cookie 或者 HTTP 回应的头信息之中,读取跨域的 Cookie,withCredentials 属性不影响这一点。

upload

XMLHttpRequest 不仅可以发送请求,还可以发送文件,这就是 AJAX 文件上传。发送文件以后,通过 XMLHttpRequest.upload 属性可以得到一个对象,通过观察这个对象,可以得知上传。主要方法就是监听这个对象的各种事件:loadstart、loadend、load、abort、error、progress、timeout。

假定网页上有一个 <progress> 元素。

<progress min="0" max="100" value="0">0% complete</progress>

文件上传时,对 upload 属性指定 progress 事件的监听函数,即可获得上传的进度。

function upload(blobOrFile) {var xhr = new XMLHttpRequest();xhr.open('POST', '/server', true);xhr.onload = function (e) {};var progressBar = document.querySelector('progress');xhr.upload.onprogress = function (e) {if (e.lengthComputable) {progressBar.value = (e.loaded / e.total) * 100;// 兼容不支持 <progress> 元素的老式浏览器progressBar.textContent = progressBar.value;}};xhr.send(blobOrFile);
}upload(new Blob(['hello world'], {type: 'text/plain'}));

XMLHttpRequest 的实例方法

open()

用于指定 HTTP 请求的参数,或者说初始化 XMLHttpRequest 实例对象。它一共可以接受五个参数。

void open(string method,string url,optional boolean async,optional string user,optional string password
);
  • method:表示 HTTP 动词方法,比如 GETPOSTPUTDELETEHEAD
  • url:表示请求发送目标 URL
  • async:表示请求是否为异步,默认为 true。如果设为 false,则 send() 方法只有等到收到服务器返回了结果,才会进行了下一步操作。该参数可选。由于同步 AJAX 请求会造成浏览器失去响应,许多浏览器已经在主线程使用,只允许 Worker 里面使用。所以,这个参数轻易不应该设为 false
  • user:用户名,默认为空字符串,可选
  • password:密码,默认为空字符串,可选

注意,如果对使用过 open() 方法的 AJAX 请求,再次使用这个方法,等同于调用 abort() ,即终止请求。

send()

用于实际发出 HTTP 请求。它的参数是可选的,如果不带参数,就表示 HTTP 请求只有一个 URL,没有数据体,典型例子就是 GET 请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。

var xhr = new XMLHttpRequest();
xhr.open('GET','http://www.example.com/?id=' + encodeURIComponent(id),true
);
xhr.send(null);

GET 请求的参数,作为查询字符串附加在 URL 后面。

var xhr = new XMLHttpRequest();
var data = 'email='+ encodeURIComponent(email)+ '&password='+ encodeURIComponent(password);xhr.open('POST', 'http://www.example.com', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(data);

注意,所有 XMLHttpRequest 的监听事件,都必须在 send() 方法调用之前设定。

send 方法的参数就是发送的数据。多种格式的数据,都可以作为它的参数。

void send();
void send(ArrayBufferView data);
void send(Blob data);
void send(Document data);
void send(String data);
void send(FormData data);

如果 send() 发送 DOM 对象,在发送之前,数据会先被串行化。如果发送二进制数据,最好是发送 ArrayBufferViewBlob对象,这使得通过 Ajax 上传文件成为可能。

下面是发送表单数据的例子。FormData对象可以用于构造表单数据。

var formData = new FormData();formData.append('username', '张三');
formData.append('email', 'zhangsan@example.com');
formData.append('birthDate', 1940);var xhr = new XMLHttpRequest();
xhr.open('POST', '/register');
xhr.send(formData);

它的效果与发送下面的表单数据是一样的。

<form id='registration' name='registration' action='/register'><input type='text' name='username' value='张三'><input type='email' name='email' value='zhangsan@example.com'><input type='number' name='birthDate' value='1940'><input type='submit' onclick='return sendForm(this.form);'>
</form>

下面的例子是使用 FormData 对象加工表单数据,然后再发送。

function sendForm(form) {var formData = new FormData(form);formData.append('csrf', 'e69a18d7db1286040586e6da1950128c');var xhr = new XMLHttpRequest();xhr.open('POST', form.action, true);xhr.onload = function() {// ...};xhr.send(formData);return false;
}var form = document.querySelector('#registration');
sendForm(form);

setRequestHeader()

用于设置浏览器发送的 HTTP 请求的头信息。该方法必须在open() 之后、send() 之前调用。如果该方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。

该方法接受两个参数。第一个参数是字符串,表示头信息的字段名,第二个参数是字段值。

xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);
xhr.send(JSON.stringify(data));

overrideMimeType()

用来指定 MIME 类型,覆盖服务器返回的真正的 MIME 类型,从而让浏览器进行不一样的处理。举例来说,服务器返回的数据类型是 text/xml,由于种种原因浏览器解析不成功报错,这时就拿不到数据了。为了拿到原始数据,我们可以把 MIME 类型改成text/plain,这样浏览器就不会去自动解析,从而我们就可以拿到原始文本了。

xhr.overrideMimeType('text/plain')

注意,该方法必须在 send() 方法之前调用。

修改服务器返回的数据类型,不是正常情况下应该采取的方法。如果希望服务器返回指定的数据类型,可以用 responseType 属性告诉服务器,就像下面的例子。只有在服务器无法返回某种数据类型时,才使用 overrideMimeType() 方法。

var xhr = new XMLHttpRequest();
xhr.onload = function(e) {var arraybuffer = xhr.response;// ...
}
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.send();

getResponseHeader()

返回 HTTP 头信息指定字段的值,如果还没有收到服务器回应或者指定字段不存在,返回 null。该方法的参数不区分大小写。

function getHeaderTime() {console.log(this.getResponseHeader("Last-Modified"));
}
var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'yourpage.html');
xhr.onload = getHeaderTime;
xhr.send();

getAllResponseHeaders()

返回一个字符串,表示服务器发来的所有 HTTP 头信息。格式为字符串,每个头信息之间使用 CRLF 分隔(回车+换行),如果没有收到服务器回应,该属性为null。如果发生网络错误,该属性为空字符串。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'foo.txt', true);
xhr.send();xhr.onreadystatechange = function () {if (this.readyState === 4) {var headers = xhr.getAllResponseHeaders();}
}

上面代码用于获取服务器返回的所有头信息。它可能是下面这样的字符串。

date: Fri, 08 Dec 2017 21:04:30 GMT\r\n
content-encoding: gzip\r\n
x-content-type-options: nosniff\r\n
server: meinheld/0.6.1\r\n
x-frame-options: DENY\r\n
content-type: text/html; charset=utf-8\r\n
connection: keep-alive\r\n
strict-transport-security: max-age=63072000\r\n
vary: Cookie, Accept-Encoding\r\n
content-length: 6502\r\n
x-xss-protection: 1; mode=block\r\n

然后,对这个字符串进行处理。

var arr = headers.trim().split(/[\r\n]+/);
var headerMap = {};arr.forEach(function (line) {var parts = line.split(': ');var header = parts.shift();var value = parts.join(': ');headerMap[header] = value;
});headerMap['content-length'] // "6502"

abort()

用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState 属性变为4,status 属性变为0。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/page.php', true);
setTimeout(function () {if (xhr) {xhr.abort();xhr = null;}
}, 5000);

XMLHttpRequest 实例的事件

readyStateChange 事件

readyState 属性的值发生改变,就会触发 readyStateChange 事件。

progress 事件

上传文件时,XMLHttpRequest 实例对象本身和实例的 upload 属性,都有一个progress 事件,会不断返回上传的进度。

var xhr = new XMLHttpRequest();function updateProgress (oEvent) {if (oEvent.lengthComputable) {var percentComplete = oEvent.loaded / oEvent.total;} else {console.log('无法计算进展');}
}xhr.addEventListener('progress', updateProgress);xhr.open();

load 事件、error 事件、abort 事件

load 事件表示服务器传来的数据接收完毕,error 事件表示请求出错,abort 事件表示请求被中断(比如用户取消请求)。

var xhr = new XMLHttpRequest();xhr.addEventListener('load', transferComplete);
xhr.addEventListener('error', transferFailed);
xhr.addEventListener('abort', transferCanceled);xhr.open();function transferComplete() {console.log('数据接收完毕');
}function transferFailed() {console.log('数据接收出错');
}function transferCanceled() {console.log('用户取消接收');
}

loadend 事件

abortloaderror 这三个事件,会伴随一个 loadend 事件,表示请求结束,但不知道其是否成功。

xhr.addEventListener('loadend', loadEnd);function loadEnd(e) {console.log('请求结束,状态未知');
}

timeout 事件

服务器超过指定时间还没有返回结果,就会触发 timeout 事件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/738610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java项目源码基于springboot的家政服务平台的设计与实现

大家好我是程序员阿存&#xff0c;在java圈的辛苦码农。辛辛苦苦板砖&#xff0c;今天要和大家聊的是一款Java项目源码基于springboot的家政服务平台的设计与实现&#xff0c;项目源码以及部署相关请联系存哥&#xff0c;文末附上联系信息 。 项目源码&#xff1a;Java基于spr…

虚拟机镜像iso下载

MSDN, 我告诉你 - 做一个安静的工具站 (itellyou.cn)

CANalyzer使用_00 概述

计划写一个专题&#xff0c;该专题主要介绍CANalyzer的使用&#xff0c;每次文档计划写一个点&#xff0c;自己不累&#xff0c;别人看着也不累&#xff0c;并且方便拓展。本文作为专题的开篇主要介绍下CANalyzer软件的背景&#xff0c;软件界面等信息。 1 软件介绍 CANalyze…

FastAPI 学习笔记

FastAPI 学习笔记 0. 引言1. 快速开始2. 升级示例代码 0. 引言 在 Python 这个充满活力的生态系统中&#xff0c;FastAPI 应运而生&#xff0c;它是一个现代的、快速的 Web 框架&#xff0c;专注于构建 RESTful API。 无论你是一名有经验的 Python 开发人员&#xff0c;还是一…

HTTP/2、HTTP/3对HTTP/1.1的性能改进和优化

HTTP/1.1 相比 HTTP/1.0 提高了什么性能&#xff1f; 性能上的改进&#xff1a; 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。 支持管道&#xff08;pipeline&#xff09;网络传输&#xff0c;只要第一个请求发出去了&#xff0c;不必等其回来&#xff0c;就可以…

Purple Pi OH鸿蒙开发板7天入门OpenHarmony开源鸿蒙教程【五】

在完成了Purple Pi OH大部分的接口测试之后&#xff0c;紧接着就是一个充满挑战的任务——利用SDK来编译生成我们自己的镜像文件。通过这一过程&#xff0c;不仅能够让你获得一个可在真实硬件上运行的系统镜像&#xff0c;更重要的是&#xff0c;它让你对OpenHarmony系统的构建…

Qt - 信号和槽

目录 一、信号 二、槽 三、信号和槽的使用 (一) 连接信号和槽 (二) 自定义槽 (三) 通过 Qt Creator生成信号槽代码 (四) 自定义信号 四、带参数的信号和槽 五、信号与槽的断开 六、Qt4版本信号与槽的连接 (一) Qt4版本信号与槽连接的优缺点 一、信号 在 Qt 中&…

CubeMX使用教程(5)——定时器PWM输出

本篇我们将利用CubeMX产生频率固定、占空比可调的两路PWM信号输出 例如PA6引脚输出100Hz的PWM&#xff1b;PA7引脚输出500Hz的PWM&#xff0c;双路同时输出 我们还是利用上一章定时器中断的工程进行学习&#xff0c;这样比较方便 首先打开CubeMX对PA6、PA7进行GPIO配置 注&a…

Mixamo动画素材导入UE5的最简单方法

一、Mixamo素材 官网&#xff1a;https://www.mixamo.com/ Mixamo是Adobe公司出品的免费动画库&#xff0c;可商用。软件分为characters(角色&#xff09;、Animations&#xff08;动画)两个部分。 二、辅助工具MIXAMO CONVERTER 官网&#xff1a;https://terribilisstudio…

C#与WPF通用类库

个人集成封装&#xff0c;仓库已公开 NetHelper 集成了一些常用的方法&#xff1b; 如通用的缓存静态操作类、常用的Wpf的ValueConverters、内置的委托类型、通用的反射加载dll操作类、Wpf的ViewModel、Command、Navigation、Messenger、部分常用UserControls(可绑定的Passwo…

通信总线协议之CAN-FD协议详解

文章目录 通信总线之CAN-FD总线协议详解1. CAN-FD 简介1.1 什么是CAN FD1.2 CAN FD的特点 2. CAN-FD总线协议2.1 帧起始2.2 仲裁段2.3 控制段2.4 数据段2.5 CRC段2.6 ACK段2.7 帧结束 3. 如何从传统的CAN升级到CAN FD 通信总线之CAN-FD总线协议详解 1. CAN-FD 简介 1.1 什么是…

selenium高级应用

常见控件应用 复杂的控件操作1.操作Ajax选项2.滑动滑块操作 WebDriver的特殊操作元素class值包含空格property、attribute、text的区别定位动态id 截图功能页面截图页面截图&#xff0c;返回截图的二进制数据页面截图&#xff0c;返回base64的字符串截取指定元素。先定位元素&a…

Redis常见数据类型下

目录 Hash 哈希 常用指令 HSET HGET HEXISTS HDEL HKEYS HVALS HGETALL HMGET 内部编码 Hash类型和关系型数据库 缓存方式对比 List 列表 特点 常用命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP / RPOP LINDEX LINSERT 阻塞(BLOCK)版…

【Linux】文件缓冲区|理解文件系统

目录 预备知识 观察现象 第一&#xff1a;携带\n&#xff0c;不使用fork()&#xff0c;打印到显示器 第二&#xff1a;携带\n&#xff0c;使用fork()&#xff0c;打印到显示器 第三&#xff1a;携带\n&#xff0c;使用fork()&#xff0c;打印到文件里 第四&#xff1a;不携…

如何选择适合的G口大流量服务器?

G口大流量服务器是指接入互联网的带宽达到1Gbps及以上&#xff0c;并且能够提供大量数据传输服务的服务器。那么如何选择适合的G口大流量服务器&#xff0c;RAK部落小编为您整理发布选择适合的G口大流量服务器需要考虑哪些关键点。 选择适合的G口大流量服务器时&#xff0c;应该…

JavaSec 基础之 CC1 链

文章目录 背景环境以及配置分析0x1 终点(利用点分析)0x20x30x310x320x33 0x040x05 背景 Apache Commons Collections是Apache提供的一个Java库&#xff0c;它扩展了Java自带的集合框架。通过这个库&#xff0c;咱们可以使用更多种类的集合类型&#xff0c;以及各种实用的集合操…

星星魔方

星星魔方 1&#xff0c;魔方三要素 &#xff08;1&#xff09;组成部件 6个中心块和8个角块和三阶魔方同构&#xff0c;另外每个面还有构成五角星的十个块。 &#xff08;2&#xff09;可执行操作 一共12种操作&#xff0c;其中6种是每个层顺时针旋转90度&#xff0c;另外6…

HTML静态网页成品作业(HTML+CSS)——家乡漳州介绍设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

Python的特性——跟老吕学Python编程

Python的特性——跟老吕学Python编程 Python的特性1.Python易学易用2.Python是解释型语言3.Python是交互式的4.Python是一种多范式语言5.Python的标准库6.Python是开源的7.Python是跨平台的8.用于GUI应用程序的Python9.Python的数据库连接10.Python是可扩展的11.Python拥有活跃…

【golang】28、用 httptest 做 web server 的 controller 的单测

文章目录 一、构建 HTTP server1.1 model.go1.2 server.go1.3 curl 验证 server 功能1.3.1 新建1.3.2 查询1.3.3 更新1.3.4 删除 二、httptest 测试2.1 完整示例2.2 实现逻辑2.3 其他示例2.4 用 TestMain 避免重复的测试代码2.5 gin 框架的 httptest 一、构建 HTTP server 1.1…