步骤 1: 下载OpenSSL

https://www.openssl.org/source/
  • 通常推荐下载最新的、非轻量版(non-light)的版本以获得完整的功能。

步骤 2: 安装OpenSSL

  1. 运行安装程序
    双击下载的安装程序文件,按提示进行安装。建议选择“Copy OpenSSL DLLs to: The OpenSSL binaries (/bin) directory”选项,以便将OpenSSL动态链接库放在可执行文件同一目录下,简化配置过程。
  2. 选择安装目录
    配置自定义安装目录:D:\myEnvironment

步骤 3: 配置环境变量

  • 更新Path变量
    在“编辑环境变量”窗口中,点击“新建(N)”并输入OpenSSL的安装目录下的bin目录路径,例如刚才的:D:\myEnvironment

步骤 4: 验证安装

输入openssl version命令并回车。如果安装成功,你将看到OpenSSL的版本信息输出。

在配置支付方式如连连支付(LianLian Pay)时
RSA公钥和私钥是一对,公钥用于加密信息,而私钥用于解密信息。

RSA 密钥对简介

RSA加密算法是基于一对密钥——公钥和私钥——工作的,这两个密钥是一起生成的。公钥和私钥在数学上是相关联的,但是设计上确保了只有生成它们的过程能够知道这种联系。公钥用于加密数据,而私钥用于解密数据。私钥还用于数字签名的生成,而公钥用于签名的验证。

生成私钥和公钥的过程涉及复杂的数学运算,包括大质数的选择和乘积,以及与之相关的一系列计算。私钥包含了这个过程中的所有秘密参数,而公钥则只包含了一部分信息,不足以还原出私钥。
这种设计确保了即使有人知道了公钥,也无法逆向工程来获取私钥。实际上,公钥可以自由共享和分发,而不会危及到私钥的安全性。这就是为什么私钥必须被严格保密,而公钥则可以公开的原因。
因此,如果你失去了私钥,就没有办法仅通过公钥来重新生成或恢复私钥。这种情况下,你需要生成一对新的密钥对,并在必要的场合(如配置支付系统)使用新的公钥。

在JavaScript中,forEach 方法和 for...of 循环都可以用于遍历数组(或类数组对象)中的元素。但是,它们在使用上有一些关键的区别:

for...of 循环

  • 更多控制:for...of 循环提供了对循环的更多控制,包括使用 break, continue 和 return(如果在函数内部)来控制循环流程。
  • 更广泛的适用性:除了数组之外,for...of 可以用来遍历任何实现了迭代协议的对象,包括字符串、Map、Set等。
  • 异步迭代:for...of 循环可以与异步迭代(for await...of)结合使用,便于处理异步迭代对象,如异步生成器函数。
  • 示例:
    for (const link of myLinks) {
    link.onclick = (e) => {
        e.preventDefault();
        const linkData = e.target.getAttribute("data-page");
        getData(linkData);
    };
    }

    forEach 方法

  • 针对数组设计:forEach 方法特定于数组,是 Array 的一个方法。它不适用于没有实现 forEach 方法的其他可迭代对象。
  • 不能使用 break 和 continue:在 forEach 函数中不能使用 break 或 continue 来退出循环或跳过当前迭代。
  • 回调函数的作用域:forEach 允许为回调函数指定一个可选的第二参数,用作回调函数内 this 的值。而在 for...of 循环中,通常通过闭包或外部变量来访问外部作用域。
  • 无法直接使用异步操作:虽然在 forEach 的回调函数中可以执行异步操作,但是 forEach 本身不会等待这些异步操作完成。如果需要处理异步操作,可能需要使用 for...of 循环结合 async/await 或其他方法。
    示例:

    myLinks.forEach((myLink) => {
    myLink.addEventListener("click", function(e) {
        e.preventDefault();
        const linkData = e.target.getAttribute("data-page");
        getData(linkData);
    })
    });
const reqHeaders = new Headers();
// a cached response is okay unless it's more than a week oldreqHeaders.set("Cache-Control", "max-age=604800");

Cache-Control 是一个 HTTP 头部字段,用于定义缓存策略。在客户端和服务端都有广泛的应用。一些常见的 Cache-Control 指令包括:

  • max-age=<seconds>: 指定一个时间长度,在这段时间内,缓存的副本仍然是新鲜的。
  • no-cache: 强制所有缓存了该响应的缓存器在使用已缓存的数据前,发送请求到原始服务器进行验证。
  • no-store: 禁止缓存,表示请求或响应中的信息不应被存储在缓存中。

appendChildappend 在 JavaScript 中都是用来向 DOM 中添加元素的方法,但它们之间存在一些差异:

appendChild

appendChild 方法是 DOM API 的一部分,用于将一个节点作为最后一个子节点添加到指定父节点中。
appendChild 只能接收一个节点作为参数,如果尝试传入非节点(如字符串),将会抛出错误。
appendChild 方法将返回被添加的节点。
使用示例:

const parentElement = document.getElementById('parent');
const newElement = document.createElement('div');
parentElement.appendChild(newElement); // 在parent元素中添加一个新的div作为子节点

append

append 方法是一个较新的 DOM API,它允许你同时向父节点添加多个子节点或字符串。
append 可以接受任意数量的参数,参数可以是 DOM 节点或者是文本。这使得它比 appendChild 更灵活。
append 不会返回任何值。
使用示例(与你提供的代码类似)

const parentElement = document.getElementById('parent');
const newElement = document.createElement('div');
const textContent = 'Hello, World!';
parentElement.append(newElement, textContent); // 在parent元素中添加一个新的div和文本'Hello, World!'作为子节点

编译C程序

  • 编译程序
    gcc hello.c -o hello

    这条命令告诉GCC编译器(gcc)去编译源文件hello.c,并将编译后的可执行文件命名为hello。如果不使用-o选项,GCC默认生成的可执行文件名为a.out(在Unix和Linux系统上)。

  • 指定编译标准
    gcc -std=c99 hello.c -o hello

    这条命令通过-std=c99选项指定使用C99标净来编译程序。你也可以根据需要选择其他标准,如c89、c11等。

  • 开启所有警告
    gcc -Wall hello.c -o hello

    使用-Wall选项让GCC显示所有警告信息,这对于发现和修正潜在的错误非常有帮助。

  • 运行C程序

运行程序

  • 在Windows上:

    ./hello

    其他有用的GCC选项

  • 生成调试信息

    gcc -g hello.c -o hello

    使用-O2选项来让GCC对代码进行优化,以提高程序运行的效率。GCC提供了不同级别的优化选项,从-O0(无优化)到-O3(尽可能强的优化),以及-Os(优化程序大小)。

  • 定义宏

    gcc -DNAME=VALUE hello.c -o hello

Response.blob()方法和Blob()构造函数都可以用来创建Blob对象,但它们的使用场景和目的有所不同。

Response.blob()

Response.blob()是Fetch API的一部分,它是在处理Fetch请求的响应时使用的。当您向一个服务器发送请求并接收到响应时,如果响应数据是二进制数据,您可以使用Response.blob()来获取这些数据的Blob对象。
例如,如果您请求一个图片或视频文件,服务器的响应可以通过Response.blob()转换为Blob对象。转换后的Blob对象可以用于多种用途,比如使用URL.createObjectURL()创建一个URL来显示这个图片或视频。
这个方法是异步的,返回一个Promise对象,这意味着您需要使用.then()方法或async/await语法来处理结果。

fetch('image.png')
  .then(response => response.blob())
  .then(blob => {
    // 使用获取到的blob对象
    const imageUrl = URL.createObjectURL(blob);
    document.querySelector('img').src = imageUrl;
  });

Blob()构造函数

Blob()构造函数用于直接在JavaScript中创建一个新的Blob对象。您可以提供一个数组作为第一个参数,数组中的每个元素都会成为Blob对象的一部分。这些元素可以是字符串、ArrayBuffer或者另一个Blob对象等。第二个参数是一个可选的对象,指定了Blob对象的属性,比如type属性来指定MIME类型。
这个构造函数主要用于在程序中动态创建二进制数据。您可以使用它来创建文件、处理文本或生成媒体内容等。

const blobParts = ['<q id="a"><span id="b">hey!</span></q>']; // 一个包含单个字符串的数组
const blob = new Blob(blobParts, { type: "text/html" }); // 得到blob
// 使用创建的blob对象
const url = URL.createObjectURL(blob);
document.querySelector('iframe').src = url;

Blob(Binary Large Object)对象表示了一个不可变的、原始数据的类文件对象。Blob对象可以表示存储在内存中的大量数据,比如图片、视频、音频或其他二进制格式的文件。通过JavaScript,我们可以用Blob来处理这些数据,实现多种功能,比如文件下载、上传、处理和转换等。

Blob的应用场景

1. 创建和下载文件

您可以使用Blob来动态创建文件内容,并允许用户下载这些文件。例如,您可以将一个文本数组转换成Blob对象,然后通过创建一个指向该Blob的URL,并将其设置为标签的href属性,实现文件的下载功能。

2. 上传文件

在前端,Blob可以用于上传文件。Blob对象可以通过AJAX或Fetch API上传到服务器。这对于上传图片或视频文件等大型文件特别有用,因为Blob可以将文件作为二进制数据传输,提高效率。

3. 从Blob对象创建URL

可以使用URL.createObjectURL()方法从Blob对象创建一个URL。这个URL可以用于在网页上显示Blob数据,例如显示图片或视频。

const blob = new Blob([document.querySelector('textarea').value], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
document.querySelector('img').src = url;

4. 处理媒体文件

Blob非常适合于处理媒体文件,比如图片,MP4视频等。例如,您可以读取用户选择的图片文件,并使用Blob来预览图片;或者,您可以通过JavaScript处理视频文件,比如截取视频的一部分或更改视频的编码格式。

5. 缓存数据

Blob也可以用于前端的数据缓存。对于从服务器获取的大型数据(如JSON数据、图片或视频文件),您可以将其存储为Blob,然后在本地缓存。当需要这些数据时,可以直接从Blob读取,避免重复从服务器加载数据,提高应用性能。

问题在script标签的type="module" 上.... 不加这个type就正常了

==>
当在<script>标签中使用type="module"时,您告诉浏览器该脚本应当作JavaScript模块来处理。这意味着:
默认严格模式:模块自动处于严格模式下,您不需要在脚本顶部显式声明"use strict";。
模块作用域:在模块脚本中声明的变量、函数等不会自动成为全局作用域的一部分。它们只存在于模块作用域内,除非您显式地导出或导入它们。
支持模块导入和导出:您可以使用import和export语句在模块之间共享代码。

在使用Parcel这类构建工具时,它负责处理模块的打包和依赖管理。如果您的项目被构建为一个单一的打包文件,而您在引入这个文件时使用了type="module",那么可能会发生一些不一致的行为,因为Parcel已经将模块和其他代码转换成了浏览器可以直接执行的格式。具体表现取决于Parcel的版本和配置,以及您的项目结构。
如果不使用type="module"属性,脚本会被当作传统的JavaScript脚本来处理,这可能和Parcel构建的输出更加兼容,特别是如果Parcel已经处理了所有必要的模块转换。
如何决定是否使用type="module"?
如果您直接在HTML中编写或引入ES模块(也就是说,不通过构建工具处理),那么使用type="module"是正确和必要的。
如果您通过构建工具(如Parcel、Webpack等)构建项目,并且构建输出是一个自包含的脚本,那么通常不需要在引用构建后的脚本时使用type="module",除非您有特定的理由或构建工具的文档特别建议这样做。