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

Web API 基础 (Web Workers API)

Web Workers API

1、指南

1.1 使用Web Workers

Web Workers是一种让Web内容在后台线程中运行脚本的简单方法。工作线程可以在不干扰用户界面的情况下执行任务。此外,它们还可以使用XMLHttpRequest(尽管responseXMLchannel属性总是为空)或fetch(没有此类限制)执行I/O。工作线程一旦被创建,就可以通过向JavaScript代码指定的事件处理程序发送消息来向创建它的JavaScript代码发送消息(反之亦然)。

本文详细介绍了如何使用web worker。

1.1.1 Dedicated workers

如上所述,Dedicated worker只能由调用它的脚本访问。在本节中,我们将讨论在 Basic dedicated worker example示例中发现的JavaScript:它允许您输入两个要相乘的数字。这些数字被发送给一个专门的工作者,相乘,结果返回到页面并显示。

这个示例相当简单,但我们决定在向您介绍基本的worker概念时保持简单。本文稍后将介绍更高级的细节。

Worker feature detection

为了更好地控制错误处理和向后兼容性,将 worker 访问代码包装在下面(main.js)中是一个好主意:

if (window.Worker) {// …
}
Spawning a dedicated worker

创建一个新的worker很简单。您所需要做的就是调用Worker()构造函数,指定要在Worker线程中执行的脚本的URI

// main.js
const myWorker = new Worker("worker.js");
向专用worker发送和从专用worker发送消息

worker的魔力是通过postMessage()方法和onmessage事件处理程序实现的。当您想要向worker发送消息时,您可以像这样向它发送消息

first.onchange = () => {myWorker.postMessage([first.value, second.value]);console.log("Message posted to worker");
};second.onchange = () => {myWorker.postMessage([first.value, second.value]);console.log("Message posted to worker");
};

这里有两个<input>元素分别由变量firstsecond表示;当其中一个的值被改变时,myWorker.postMessage([first.value,second.value])被用来将两者中的值以数组的形式发送给worker。你可以在消息中发送任何你喜欢的东西。

在worker中,当收到消息时,我们可以通过编写这样的事件处理程序块来响应:

// worker.js
onmessage = (e) => {console.log("Message received from main script");const workerResult = `Result: ${e.data[0] * e.data[1]}`;console.log("Posting message back to main script");postMessage(workerResult);
};

onmessage处理程序允许我们在接收到消息时运行一些代码,消息本身在message 事件的data属性中可用。这里我们将两个数字相乘,然后再次使用postMessage(),将结果发送回主线程。

回到主线程,我们再次使用onmessage来响应从worker发送回来的消息:

myWorker.onmessage = (e) => {result.textContent = e.data;console.log("Message received from worker");
};

这里我们获取消息事件数据并将其设置为result段落的textContent,这样用户就可以看到计算的结果。

结束 worker

如果你需要在主线程中立即终止一个正在运行的worker,你可以通过调用worker的terminate方法来完成:

myWorker.terminate();

工作线程被立即终止。

处理错误

当工作线程中发生运行时错误时,将调用其onerror事件处理程序。它接收一个名为error的事件,该事件实现了ErrorEvent接口。

事件不会冒泡并且可以取消;为了防止默认操作发生,worker可以调用错误事件的preventDefault()方法。

错误事件有以下三个感兴趣的字段:

  • message
    一个人类可读的错误信息。
  • filename
    发生错误的脚本文件的名称。
  • lineno
    发生错误的脚本文件的行号。
Spawning subworkers

如果workers 愿意,他们可能会产生更多的workers 。所谓的子worker必须托管在与父页面相同的源中。此外,子worker的uri是相对于父worker的位置而不是所属页面的位置进行解析的。这使得workers 更容易跟踪他们的依赖项在哪里。

导入脚本和库

工作线程可以访问全局函数importScripts(),该函数允许它们导入脚本。它接受零个或多个uri作为要导入的资源的参数;以下所有例子都是正确的:

importScripts(); /* imports nothing */
importScripts("foo.js"); /* imports just "foo.js" */
importScripts("foo.js", "bar.js"); /* imports two scripts */
importScripts("//example.com/hello.js",
); /* You can import scripts from other origins */

浏览器加载列出的每个脚本并执行它。然后,worker可以使用每个脚本中的任何全局对象。如果无法加载脚本,则抛出NETWORK_ERROR,并且不会执行后续代码。之前执行的代码(包括使用setTimeout()延迟的代码)仍然可以使用。还保留了importScripts()方法之后的函数声明,因为它们总是在其余代码之前求值。

1.1.2 Shared workers

一个共享的工作线程可以被多个脚本访问——即使它们被不同的窗口、iframe甚至工作线程访问。在本节中,我们将讨论基 Basic shared worker example示例中的JavaScript(运行shared worker):这与basic dedicated worker 示例非常相似,除了它有两个可用的函数,由不同的脚本文件处理:两个数字的乘法,或一个数字的平方。两个脚本都使用同一个worker来执行所需的实际计算。

在这里,我们将集中讨论 dedicated workers 和shared workers之间的区别。请注意,在这个示例中,我们有两个HTML页面,每个页面都应用了使用相同工作文件的JavaScript。

生成一个 shared worker

生成一个新的共享工作线程与 dedicated 工作线程非常相似,但使用不同的构造函数名称(参见index.htmlindex2.html) -每个构造函数都必须使用如下代码启动工作线程:

const myWorker = new SharedWorker("worker.js");

一个很大的区别是,对于共享工作线程,您必须通过port 对象进行通信—打开一个显式端口,脚本可以使用该端口与工作线程进行通信(这在 dedicated 工作线程的情况下隐式完成)。

端口连接需要通过使用onmessage事件处理程序隐式启动,或者在发布任何消息之前显式地使用start()方法启动。只有当消息事件通过addEventListener()方法连接时才需要调用start()

注意:当使用start()方法打开端口连接时,如果需要双向通信,则需要从父线程和工作线程都调用该方法。

向共享worker发送消息和从共享worker发送消息

现在消息可以像以前一样发送到worker,但是postMessage()方法必须通过port对象调用(同样,你会在 multiply.jssquare.js中看到类似的结构):

// square.js/multiply.js
squareNumber.onchange = () => {myWorker.port.postMessage([squareNumber.value, squareNumber.value]);console.log("Message posted to worker");
};

现在,来看看worker。这里也有一点复杂

onconnect = (e) => {const port = e.ports[0];port.onmessage = (e) => {const workerResult = `Result: ${e.data[0] * e.data[1]}`;port.postMessage(workerResult);};
};

首先,当端口连接发生时,我们使用onconnect处理程序来触发代码(例如,当父线程中的onmessage事件处理程序被设置时,或者当父线程中显式调用start()方法时)。

我们使用该事件对象的ports属性来获取端口并将其存储在一个变量中。

接下来,我们在端口上添加一个onmessage处理程序来执行计算并将结果返回给主线程。在工作线程中设置这个onmessage处理程序也会隐式地打开到父线程的端口连接,因此实际上不需要调用port.start(),如上所述。

最后,回到主脚本,我们处理消息(同样,您将在multi .js和square.js中看到类似的结构)。

// multiply.js and square.js
myWorker.port.onmessage = (e) => {result2.textContent = e.data;console.log("Message received from worker");
};

当消息通过端口从worker返回时,我们将计算结果插入到适当的结果段落中。

1.2 Web worker可用的函数和类

除了标准的JavaScript函数集(如StringArrayObjectJSON等)之外,还有各种各样的函数可以从DOM中提供给worker。本文提供了一个列表。

Worker Contexts & Functions

工作线程运行在与当前窗口(window)不同的全局上下文中!虽然Window不是直接对worker可用,但许多相同的方法都是在一个共享的mixin (WindowOrWorkerGlobalScope)中定义的,并且通过worker自己的WorkerGlobalScope派生的上下文提供给worker使用:

  • DedicatedWorkerGlobalScope for dedicated workers
  • SharedWorkerGlobalScope for shared workers
  • ServiceWorkerGlobalScope for service workers

一些函数(一个子集)是所有工作线程和主线程(来自WindowOrWorkerGlobalScope)共同的:

  • atob()
  • btoa()
  • clearInterval()
  • clearTimeout()
  • dump() Non-standard
  • queueMicrotask()
  • setInterval()
  • setTimeout()
  • structuredClone()
  • window.requestAnimationFrame (dedicated workers only)
  • window.cancelAnimationFrame (dedicated workers only)

以下函数仅对worker可用:

  • WorkerGlobalScope.importScripts() (all workers)
  • DedicatedWorkerGlobalScope.postMessage (dedicated workers only)

worker中可用的Web APIs

注意:如果列出的API在特定版本中被平台支持,那么通常可以认为它在web worker中可用。您还可以使用网站https://worker-playground.glitch.me/测试对特定对象/函数的支持

1.3 结构化克隆算法

结构化克隆算法复制复杂的JavaScript对象。它在调用structuredClone()时内部使用,通过postMessage()在 worker 之间传输数据,使用IndexedDB存储对象,或为其他api复制对象。

它通过递归遍历输入对象进行克隆,同时维护以前访问过的引用的映射,以避免无限遍历循环。

结构化克隆不适用的东西

  • 函数对象不能被结构化克隆算法复制;试图抛出DataCloneError异常。
  • 克隆 DOM 节点同样会抛出DataCloneError异常。
  • 某些对象属性不保留:
    • 不保留RegExp对象的lastIndex属性。
    • 属性描述符、setter、getter和类似元数据的特性不复制。例如,如果一个对象用属性描述符标记为只读,那么它将在副本中被读/写,因为这是默认的。
    • 原型链(prototype chain)不会被遍历或复制。

支持的类型

JavaScript types
Error types
Web/API types

1.4 Transferable objects

可转移对象(Transferable objects)是拥有资源的对象,这些资源可以从一个上下文中转移到另一个上下文中,从而确保资源一次只在一个上下文中可用。转移后,原对象不再可用;它不再指向传输的资源,并且任何读取或写入该对象的尝试都会抛出异常。

可转移对象通常用于共享一次只能安全地暴露给单个JavaScript线程的资源。例如,ArrayBuffer是一个可转移的对象,它拥有一块内存。当这样的缓冲区在线程之间传输时,相关的内存资源将从原始缓冲区中分离出来,并附加到新线程中创建的缓冲区对象上。原始线程中的缓冲区对象不再可用,因为它不再拥有内存资源。

在使用structuredClone()创建对象的深度拷贝时也可能使用Transferring 。克隆操作之后,转移的资源将被移动,而不是复制到克隆对象中。

用于传输对象资源的机制取决于对象本身。例如,当在线程之间传输ArrayBuffer时,它所指向的内存资源实际上是在上下文之间以快速有效的零复制操作移动的。其他对象可以通过复制相关资源然后从旧上下文中删除来传输。

并不是所有的对象都是可转移的。下面提供了可转移对象的列表。

在线程之间传输对象

下面的代码演示了将消息从主线程发送到web worker线程时传输是如何工作的。Uint8Array在工作中被复制(复制),而它的缓冲区被转移。传输后,从主线程读取或写入uInt8Array的任何尝试都会抛出,但您仍然可以检查byteLength以确认它现在为零。

// Create an 8MB "file" and fill it. 8MB = 1024 * 1024 * 8 B
const uInt8Array = new Uint8Array(1024 * 1024 * 8).map((v, i) => i);
console.log(uInt8Array.byteLength); // 8388608// Transfer the underlying buffer to a worker
worker.postMessage(uInt8Array, [uInt8Array.buffer]);
console.log(uInt8Array.byteLength); // 0

注意:类型化数组,如Int32ArrayUint8Array,是可序列化的,但不可转移。然而,它们的底层缓冲区是ArrayBuffer,这是一个可转移的对象。我们可以在data参数发送uInt8Array.buffer。而不是传输数组中的uInt8Array

克隆操作期间的转移

下面的代码显示了structuredClone()操作,其中底层缓冲区从原始对象复制到克隆对象。

const original = new Uint8Array(1024);
const clone = structuredClone(original);
console.log(original.byteLength); // 1024
console.log(clone.byteLength); // 1024original[0] = 1;
console.log(clone[0]); // 0// Transferring the Uint8Array would throw an exception as it is not a transferable object
// const transferred = structuredClone(original, {transfer: [original]});// We can transfer Uint8Array.buffer.
const transferred = structuredClone(original, { transfer: [original.buffer] });
console.log(transferred.byteLength); // 1024
console.log(transferred[0]); // 1// After transferring Uint8Array.buffer cannot be used.
console.log(original.byteLength); // 0

Supported objects

注意:可转移对象在Web IDL文件中被标记为属性[Transferable]

2、接口

2.1 DedicatedWorkerGlobalScope

可以通过self关键字访问DedicatedWorkerGlobalScope对象(Worker全局作用域)。JavaScript Reference中列出了一些额外的全局函数、命名空间对象和构造函数,它们通常不与worker全局作用域关联,但在它上可用。参见:Functions available to workers.。
在这里插入图片描述

2.2 ServiceWorker

2.3 SharedWorker

2.4 SharedWorkerGlobalScope

2.5 Worker

Web Workers API 的Worker接口代表了一个可以通过脚本创建的后台任务,它可以将消息发送回它的创建者。

通过调用Worker("path/to/worker/script")构造函数来创建 worker。

Workers 可以自己产生新的Workers ,只要这些Workers 被托管在与父页相同的origin。

并不是所有的接口和函数都对 Worker中 的脚本可用。Workers 可以使用XMLHttpRequest进行网络通信,但是它的responseXMLchannel属性总是为null。(fetch也是可用的,没有这样的限制。)

在这里插入图片描述

构造函数

Worker()

创建一个专用(dedicated)的web worker,执行指定的URL处的脚本。这也适用于 Blob URLs。该脚本必须遵守同源策略。

注意:浏览器制造商对于数据URL是否同源存在分歧。虽然Firefox 10及以后的版本接受数据url,但并非所有其他浏览器都是如此。

new Worker(aURL)
new Worker(aURL, options)
  • aURL
    一个字符串,表示工作线程将要执行的脚本的URL。它必须遵守同源策略。

  • options 可选
    一个对象,其中包含可在创建对象实例时设置的选项属性。可用的属性如下:

    • type
      指定要创建的工作线程类型的字符串。取值为classicmodule。如果未指定,则使用的默认值为classic

    • credentials
      指定工作线程使用的凭据类型的字符串。该值可以是omitsame-origininclude。如果没有指定,或者如果type是classic,则默认使用omit (不需要凭据)。

    • name
      一个字符串,指定用于表示工作器范围的DedicatedWorkerGlobalScope的标识名,主要用于调试目的。

实例方法

  • Worker.postMessage()
    发送一个消息——由任何JavaScript对象组成——到worker的内部作用域。

Worker postMessage()方法委托给MessagePort postMessage()方法,该方法在事件循环中添加一个与接收MessagePort相对应的任务。

Worker可以使用DedicatedWorkerGlobalScope.postMessage方法将信息发送回生成它的线程。

postMessage(message)
postMessage(message, options)
postMessage(message, transfer)
  • message
    交付给worker的对象;这将在交付给DedicatedWorkerGlobalScope.message_event 事件的data 字段中。这可以是由结构化克隆算法处理的任何值或JavaScript对象,其中包括循环引用。
    如果没有提供消息参数,解析器将抛出SyntaxError。如果要传递给worker的数据不重要,则可以显式传递nullundefined

  • options 可选
    一个可选对象,它包含一个transfer 字段,该字段包含一组要传输其所有权的可传输对象。如果对象的所有权被转移,它将在发送它的上下文中变得不可用,并且只对发送它的 worker 可用。

  • transfer 可选
    可转移对象的可选数组,用于转移其所有权。如果对象的所有权被转移,它将在发送它的上下文中变得不可用,并且只对发送它的worker 可用。
    可转移对象是类的实例,如ArrayBuffer, MessagePort或ImageBitmap对象可以被转移。null不是可接受的transfer值。

注意: postMessage()一次只能发送一个对象。如上所示,如果你想传递多个值,你可以发送一个数组。

  • Worker.terminate()
    立即终止 worker。这不会让worker完成它的操作;它立刻停止了。ServiceWorker实例不支持此方法。

事件

  • error
    在工作线程中发生错误时触发。

  • message
    当worker的父进程收到来自该worker的消息时触发。

  • messageerror
    当Worker对象接收到无法反序列化的消息时触发。

  • rejectionhandled
    每次Promise被拒绝时触发,不管是否有处理程序来捕获拒绝。

  • unhandledrejection
    当Promise拒绝而没有处理程序捕获拒绝时触发。

Example

下面的代码片段使用Worker()构造函数创建一个Worker对象,然后使用该Worker对象:

const myWorker = new Worker("/worker.js");
const first = document.querySelector("input#number1");
const second = document.querySelector("input#number2");first.onchange = () => {myWorker.postMessage([first.value, second.value]);console.log("Message posted to worker");
};

有关完整示例,请参阅我们的 Basic dedicated worker example

2.6 WorkerGlobalScope

Web Workers API的WorkerGlobalScope接口是一个表示任何worker的作用域的接口。Workers 没有浏览器上下文;这个范围包含通常由Window对象传递的信息——在本例中是事件处理程序、控制台或相关的WorkerNavigator对象。每个WorkerGlobalScope都有自己的事件循环。

这个接口通常被每个worker类型特例化:dedicated worker的专用 DedicatedWorkerGlobalScope , shared worker的共享SharedWorkerGlobalScope, ServiceWorker的ServiceWorkerGlobalScope。self属性返回每个上下文的专用范围。

在这里插入图片描述

Example

你不能在代码中直接访问WorkerGlobalScope;然而,它的属性和方法是由更具体的全局作用域继承的,比如DedicatedWorkerGlobalScopeSharedWorkerGlobalScope。例如,你可以将另一个脚本导入到worker中,并使用以下两行打印出worker作用域的导航器对象的内容:

importScripts("foo.js");
console.log(navigator);

2.7 WorkerLocation

WorkerLocation接口定义了Worker执行的脚本的绝对位置。这样的对象为每个worker初始化,并通过WorkerGlobalScope可用。通过调用self.location获得的Location属性。

2.8 WorkerNavigator

WorkerNavigator接口表示允许从 Worker 访问的Navigator接口的一个子集。这样的对象为每个Worker初始化,并通过self.navigator属性可用。

在这里插入图片描述

相关文章:

Web API 基础 (Web Workers API)

Web Workers API 1、指南 1.1 使用Web Workers Web Workers是一种让Web内容在后台线程中运行脚本的简单方法。工作线程可以在不干扰用户界面的情况下执行任务。此外&#xff0c;它们还可以使用XMLHttpRequest(尽管responseXML和channel属性总是为空)或fetch(没有此类限制)执…...

如何看待程序员不写注释?

程序员对代码注释可以说是又爱又恨又双标……你是怎么看待程序员不写注释这一事件的呢&#xff1f; 对于程序员来说&#xff0c;注释是一种非常重要的实践&#xff0c;可以帮助他们自己和其他人更好地理解和维护代码。以下是一些关于注释的观点&#xff1a; 维护代码的重要性&a…...

2.6 方法

思维导图&#xff1a; 2.6.1 什么是方法 ### 2.6.1 什么是方法 **定义**: - 方法就是一段可以重复调用的代码&#xff0c;使得程序的可读性、可维护性都得以提高。 **示例**: - 假设有一个游戏中需要反复发射炮弹。而发射炮弹的代码有100行。为了避免在程序中多次写下这100…...

【排序算法】插入排序

文章目录 一&#xff1a;基本概念1.1 介绍1.2 原理1.3 插入排序法思想 二&#xff1a;代码实现2.1 源码2.2 执行结果2.3 测试八万条数据 三&#xff1a;算法分析3.1 时间复杂度3.2 空间复杂度3.3 稳定性 一&#xff1a;基本概念 1.1 介绍 插入式排序属于内部排序法&#xff0…...

Gnuradio+AM解调

1. https://wiki.gnuradio.org/index.php/PLL_Carrier_Tracking 2. https://wiki.gnuradio.org/index.php?titleComplex_to_Mag#Example_Flowgraph...

解决java.io.IOException: Broken pipe的报错

问题说明&#xff1a; 订单服务&#xff0c;查询预售但是出现Broken pipe&#xff1b; 测试版是正常的&#xff0c;正式版报错 解决方案 1、延长客户端超时时间 // 查询预售单列表 export function listPreOrder(query) {return request({url: /order/presale/list,method:…...

微信小程序--》从模块小程序项目案例23.10.09

配置导航栏 导航栏是小程序的门户&#xff0c;用户进来第一眼看到的便是导航栏&#xff0c;其起着对当前小程序主题的概括。而我们 新建的小程序 时&#xff0c;第一步变开始配置导航栏。如下&#xff1a; 配置tabBar 因为配置tabBar需要借助字体图标&#xff0c;我这里平常喜…...

爱尔眼科角膜塑形镜验配超百万,全力做好“角塑镜把关人”

你知道吗?过去的2022年&#xff0c;我国儿童青少年总体近视率为53.6%&#xff0c;其中6岁儿童为14.5%&#xff0c;小学生为36%&#xff0c;初中生为71.6%&#xff0c;高中生为81%①。儿童青少年眼健康问题俨然成为全社会关心的热点与痛点&#xff0c;牵动着每一个人的神经。 好…...

机器学习DAYX:线性回归与逻辑回归

线性回归 多重线性回归 逻辑回归...

【网络安全】网络安全的最后一道防线——“密码”

网络安全的最后一道防线——“密码” 前言超星学习通泄露1.7亿条信息事件武汉市地震监测中心遭境外网络攻击事件 一、密码起源1、 古代密码2、近代密码3、现代密码4、量子密码 二、商密专栏推荐三、如何利用密码保护账号安全&#xff1f;1、账号安全的三大危险&#xff1f;&…...

unity操作_光源组件 c#

准备工作 添加资源导入后先不管&#xff0c;现在主要学习自带Directional Light 我们首先创建一个平面Plane 然后重置一下位置 然后创建一个Cube 也重置一下位置然后修改y0.5刚好在这个平面上 ctrl d复制一个Cube 修改位置和旋转角度 给物体一个颜色 接下来创建一个点光源 我们…...

2023年全球市场氮化铝外延片总体规模、主要生产商、主要地区、产品和应用细分研究报告

按收入计&#xff0c;2022年全球氮化铝外延片收入大约9百万美元&#xff0c;预计2029年达到25百万美元&#xff0c;2023至2029期间&#xff0c;年复合增长率CAGR为 16.1%。同时2022年全球氮化铝外延片销量大约 &#xff0c;预计2029年将达到 。2022年中国市场规模大约为 百万美…...

C++特性:继承,封装,多态

继承 封装 类把⾃⼰的数据和⽅法只让可信的类或者对象操作&#xff0c;对不可信的进⾏隐藏&#xff0c;如&#xff1a;将公共的数据或⽅法使⽤public修饰&#xff0c;⽽不希望被访问的数据或⽅法采⽤private修饰 多态 即向不同对象发送同⼀消息&#xff0c;不同的对象在接收…...

交通物流模型 | 基于双向时空自适应Transformer的城市交通流预测

城市交通流预测是智能交通系统的基石。现有方法侧重于时空依赖建模,而忽略了交通预测问题的两个内在特性。首先,不同预测任务的复杂性在不同的空间(如郊区与市中心)和时间(如高峰时段与非高峰时段)上分布不均匀。其次,对过去交通状况的回忆有利于对未来交通状况的预测。基于…...

【香橙派-OpenCV-Torch-dlib】TF损坏变成RAW格式解决方案及python环境配置

前言 本文将介绍在香橙派&#xff08;Orange Pi&#xff09;开发板上进行软件配置和环境搭建的详细步骤&#xff0c;以便运行Python应用程序。这涵盖了以下主要内容&#xff1a; 获取所需软件&#xff1a;提供了香橙派操作系统和balenaEtcher工具的下载链接&#xff0c;以确保…...

HDMI协议介绍(五)--Audio

基础知识 I2S(inter-IC sound bus)飞利浦公司制定的标准&#xff0c;既规定了硬件接口规范&#xff0c;也规定了数字音频数据格式。 硬件接口规范 I2S接口有3个主要信号&#xff1a; 时钟信号 Serial Clock 串行时钟SCK&#xff0c;也叫位时钟&#xff08;BCLK&#xff09;&…...

Centos7中安装Jenkins教程

1.必须先配置jdk环境&#xff0c;安装jdk参考 Linux配置jdk 2.先卸载Jenkins # rpm卸载 rpm -e jenkins # 检查是否卸载成功 rpm -ql jenkins # 彻底删除残留文件 find / -iname jenkins | xargs -n 1000 rm -rf 3.安装Jenkins 在 /usr/ 目录下创建 jenkins文件夹 mkdir -p je…...

十一、WSGI与Web框架

目录 一、什么是WSGI1.1 WSGI接口的组成部分1.2 关于environ 二、简易的web框架实现2.1 文件结构2.2 在web/my_web.py定义动态响应内容2.3 在html/index.html中定义静态页面内容2.4 在web_server.py中实现web服务器框架2.5 测试 三、让简易的web框架动态请求支持多页面3.1 修改…...

[idekCTF 2022]Paywall - LFI+伪协议+filter_chain

[idekCTF 2022]Paywall 一、解题流程&#xff08;一&#xff09;、分析&#xff08;二&#xff09;、解题 二、思考总结 一、解题流程 &#xff08;一&#xff09;、分析 点击source可以看到源码&#xff0c;其中关键部分&#xff1a;if (isset($_GET[p])) {$article_content…...

Python 自动化Web测试

限于作者水平有限&#xff0c;以下内容可能是管窥之见&#xff0c;希望大家高抬贵手&#xff0c;且让我斗胆抛砖引玉。 公司产品迪备主要是通过网页操作来进行数据库的备份与恢复&#xff0c;监控与管理&#xff0c;因此在测试的过程中&#xff0c;可以用python测试脚本来模拟…...

MM-Camera架构-Preview 流程分析

目录 文章目录 1 log开的好&#xff0c;问题都能搞2 lib3 preview3.1 打开视频流3.1.1 cpp\_module\_start\_session3.1.2 cpp\_thread\_create3.1.3 cpp\_thread\_funcsundp-3.1 cpp\_hardware\_open\_subdev(ctrl->cpphw)sundp-3.2 cpp\_hardware\_process\_command(ctrl-…...

科普文章|一文了解平行链及其优势

平行链是一种可以连接到更大规模的区块链网络&#xff08;波卡&#xff09;的独立区块链。不同于传统区块链&#xff08;如比特币和以太坊&#xff09;是孤立的并且无法在本地相互通信&#xff0c;平行链与其他平行链并行运行&#xff0c;并且相互可以无缝通信。平行链还使用波…...

Tomcat 9.0.41在IDEA中乱码问题(IntelliJ IDEA 2022.1.3版本)

1. 乱码的产生是由于编码和解码的编码表不一致引起的。 2. 排查乱码原因 2.1 在idea中启动Tomcat时控制台乱码排查 Tomcat输出日志乱码: 首先查看IDEA控制台&#xff0c;检查发现默认编码是GBK。 再查看Tomcat日志&#xff08;conf文件下logging.properties&#xff09;的默…...

在Kubernetes中实现gRPC流量负载均衡

在尝试将gRPC服务部署到Kubernetes集群中时&#xff0c;一些用户&#xff08;包括我&#xff09;面临的挑战之一是实现适当的负载均衡。在深入了解如何平衡gRPC的方式之前&#xff0c;我们首先需要回答一个问题&#xff0c;即为什么需要平衡流量&#xff0c;如果Kubernetes已经…...

Floorplanning with Graph Attention

Floorplanning with Graph Attention DAC ’22 目录 Floorplanning with Graph Attention摘要1.简介2.相关工作3.问题公式化4. FLORA的方法4.1 解决方案概述4.2 C-谱聚类算法 4.3 基于GAT的模型4.4 合成训练数据集生成 摘要 布图规划一直是一个关键的物理设计任务&#xff0…...

centos7 配置coreboot编译环境 以及编译问题解决

需要的配置 (有的资源在国外可能需要翻墙) 操作系统: centos7.9 参考文章 coreboot源码分析之编译和运行coreboot - 知乎 //coreboot编译总说明 https://www.coreboot.org/Build_HOWTO#Requirements https://poe.com/ChatGPT 注意: 因为github不稳定 所以gitee为主 1. 下载…...

大型语言模型:RoBERTa — 一种鲁棒优化的 BERT 方法

一、介绍 BERT模型的出现导致了NLP的重大进展。BERT的架构源自Transformer&#xff0c;在各种下游任务上实现了最先进的结果&#xff1a;语言建模&#xff0c;下一句预测&#xff0c;问答&#xff0c;NER标记等。 大型语言模型&#xff1a;BERT — 来自变压器的双向编码器表示 …...

解析navicate数据库密码

在线运行地址:代码在线运行 - 在线工具 <?php class NavicatPassword {protected $version 0;protected $aesKey libcckeylibcckey;protected $aesIv libcciv libcciv ;protected $blowString 3DC5CA39;protected $blowKey null;protected $blowIv null;public func…...

mysql字段类型与oracle字段类型对应关系

MySQL与Oracle两种数据库在工作中&#xff0c;都是用的比较多的数据库&#xff0c;由于MySQL与Oracle在数据类型上有部分差异&#xff0c;在我们迁移数据库时&#xff0c;会遇上一定的麻烦&#xff0c;下面介绍MySQL与Oracle数据库数据类型的对应关系。 一、常见数据类型在MyS…...

linux 中 tar \ zip 解压错误后撤回

#zip zipinfo -1 path/xx.zip | xargs rm -rf#tar tar -tf xx.tar | xargs rm -rf...