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

axios的使用

在 Vue 项目中,封装 Axios 并实现加密、重复请求优化、请求取消、页面切换时取消未完成的请求、以及区分上传和下载操作是非常常见的需求。下面将逐一讲解这些需求的实现方式。

1. Axios 的基本封装

首先,我们可以将 Axios 封装到一个服务层中,方便统一管理请求和拦截。

// src/utils/request.js
import axios from 'axios';
import { encryptRequestData, decryptResponseData } from './crypto'; // 假设有加密解密工具
import { ElMessage } from 'element-plus'; // UI 组件库的消息提示// 创建 axios 实例
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // api base_urltimeout: 5000, // 请求超时时间
});// 请求拦截器
service.interceptors.request.use((config) => {// 请求加密if (config.data) {config.data = encryptRequestData(config.data); // 数据加密}// token 放入 header 以防用户身份验证const token = localStorage.getItem('token');if (token) {config.headers['Authorization'] = `Bearer ${token}`;}return config;},(error) => {return Promise.reject(error);}
);// 响应拦截器
service.interceptors.response.use((response) => {// 响应解密if (response.data) {response.data = decryptResponseData(response.data); // 数据解密}return response;},(error) => {ElMessage.error('请求失败');return Promise.reject(error);}
);export default service;

2. 前后端加密的使用

前后端的加密一般是基于某种加密算法(例如 AES 或 RSA)。这里假设你有现成的加密和解密工具,可以在请求拦截器中对请求进行加密,在响应拦截器中对响应进行解密。

  • 加密:请求数据通过加密函数处理,传输给后端的就是密文。
  • 解密:响应数据通过解密函数还原为可读内容。
// utils/crypto.js
import CryptoJS from 'crypto-js';// 加密函数
export function encryptRequestData(data) {const key = CryptoJS.enc.Utf8.parse('16characterskey'); // 密钥const iv = CryptoJS.enc.Utf8.parse('16charactersiv ');  // 偏移量const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});return encrypted.toString();
}// 解密函数
export function decryptResponseData(ciphertext) {const key = CryptoJS.enc.Utf8.parse('16characterskey'); // 密钥const iv = CryptoJS.enc.Utf8.parse('16charactersiv ');  // 偏移量const bytes = CryptoJS.AES.decrypt(ciphertext, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});const decryptedData = bytes.toString(CryptoJS.enc.Utf8);return JSON.parse(decryptedData);
}

3. 重复请求的优化

为避免同一请求短时间内被多次发送,可以通过 axios 的请求拦截器实现防重复请求的功能。可以使用一个 Map 来存储每个请求的唯一标识,当同一请求发送时进行检查,防止重复发送。

const pendingRequests = new Map();const getRequestKey = (config) => {const { method, url, params, data } = config;return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&');
};// 添加请求拦截器
service.interceptors.request.use((config) => {const requestKey = getRequestKey(config);if (pendingRequests.has(requestKey)) {config.cancelToken = new axios.CancelToken((cancel) => {cancel(`Duplicate request: ${requestKey}`);});} else {pendingRequests.set(requestKey, config);}return config;},(error) => {return Promise.reject(error);}
);// 添加响应拦截器
service.interceptors.response.use((response) => {const requestKey = getRequestKey(response.config);pendingRequests.delete(requestKey); // 移除完成的请求return response;},(error) => {if (axios.isCancel(error)) {console.warn(error.message); // 重复请求被取消} else {// 其他错误处理}return Promise.reject(error);}
);

4. 单个请求的取消控制

对于单个请求,你可以使用 axios.CancelToken 来控制某个请求的取消。

const source = axios.CancelToken.source();// 发起请求时传入取消 token
service({url: '/some-endpoint',method: 'get',cancelToken: source.token
}).then((response) => {console.log('请求成功', response);}).catch((error) => {if (axios.isCancel(error)) {console.log('请求被取消', error.message);}});// 在需要的时候取消请求
source.cancel('取消请求');

5. 页面切换时取消未完成的请求

可以在 Vue 路由的 beforeRouteLeave 钩子中控制页面切换时取消未完成的请求。

export default {data() {return {requestSource: null, // 存储取消 token};},methods: {fetchData() {this.requestSource = axios.CancelToken.source();service.get('/api/data', { cancelToken: this.requestSource.token }).then(response => {console.log('请求成功', response);}).catch(error => {if (axios.isCancel(error)) {console.log('请求被取消');} else {console.error('请求错误', error);}});}},beforeRouteLeave(to, from, next) {if (this.requestSource) {this.requestSource.cancel('页面切换取消请求');}next();}
};

6. 区分上传和下载的使用

  • 上传文件:通常通过 FormData 来上传文件,并在 onUploadProgress 中监控上传进度。
let formData = new FormData();
formData.append('file', file);service.post('/upload', formData, {headers: {'Content-Type': 'multipart/form-data'},onUploadProgress: (progressEvent) => {let progress = (progressEvent.loaded / progressEvent.total) * 100;console.log(`上传进度: ${progress}%`);}
});
  • 下载文件:下载文件时可以指定 responseTypeblob,并处理文件保存。
service.get('/download', {responseType: 'blob',onDownloadProgress: (progressEvent) => {let progress = (progressEvent.loaded / progressEvent.total) * 100;console.log(`下载进度: ${progress}%`);}
}).then(response => {const url = window.URL.createObjectURL(new Blob([response.data]));const link = document.createElement('a');link.href = url;link.setAttribute('download', 'file.pdf'); // 下载文件名document.body.appendChild(link);link.click();
});

总结

  • Axios 的封装统一管理请求和拦截。
  • 使用加密、解密函数对请求和响应数据进行保护。
  • 防止重复请求,通过 requestKey 唯一标识每个请求。
  • 提供单个请求取消和页面切换时取消未完成请求的机制。
  • 针对上传、下载分别进行处理,监听进度。

根据这些实现,你可以根据需求进一步调整封装的细节和功能。

可以结合 vue-router 的导航守卫使用,尤其是在页面切换时取消未完成的请求。通过在 vue-router 的钩子函数(例如 beforeRouteLeavebeforeEach)中调用 axios 的取消方法,可以确保在用户切换页面时及时取消正在进行的请求,避免无效请求消耗资源。

实现步骤

  1. 创建一个全局的取消请求管理工具:使用一个 Map 来存储每个页面的取消请求函数(CancelToken),当页面切换时从 Map 中找到对应的取消方法并执行。

  2. 在路由守卫中调用取消方法:在 beforeEachbeforeRouteLeave 钩子中调用取消请求的逻辑,确保切换路由时清理未完成的请求。

具体实现方案

1. 取消请求的封装

我们可以在 axios 的封装文件中为每个请求生成一个取消令牌(CancelToken),并将其存储在全局的 cancelMap 中。

// src/utils/request.js
import axios from 'axios';const cancelMap = new Map(); // 全局的取消请求管理工具const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // API 基础路径timeout: 10000, // 超时时间
});// 请求拦截器
service.interceptors.request.use((config) => {const source = axios.CancelToken.source(); // 创建一个取消令牌config.cancelToken = source.token; // 将取消令牌附加到请求中// 使用唯一的标识(例如:URL+请求方式)来存储取消令牌const requestKey = `${config.url}&${config.method}`;cancelMap.set(requestKey, source.cancel); // 存储取消请求函数return config;},(error) => {return Promise.reject(error);}
);// 响应拦截器
service.interceptors.response.use((response) => {// 请求成功后,删除对应的取消函数const requestKey = `${response.config.url}&${response.config.method}`;cancelMap.delete(requestKey);return response;},(error) => {// 如果请求被取消,不做其他处理if (axios.isCancel(error)) {console.log('请求被取消');}return Promise.reject(error);}
);// 取消未完成的请求
export function cancelPendingRequests() {cancelMap.forEach((cancel) => {cancel('路由切换取消请求'); // 执行取消函数});cancelMap.clear(); // 清空取消函数
}export default service;
2. vue-router 中使用取消逻辑

接下来我们在 vue-router 中添加导航守卫,确保在每次路由切换时都调用 cancelPendingRequests 来取消未完成的请求。

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import { cancelPendingRequests } from '@/utils/request'; // 引入取消请求方法
import Home from '@/views/Home.vue';
import About from '@/views/About.vue';const routes = [{path: '/',name: 'Home',component: Home,},{path: '/about',name: 'About',component: About,},
];const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes,
});// 全局路由守卫 - 在每次路由切换前,取消未完成的请求
router.beforeEach((to, from, next) => {cancelPendingRequests(); // 取消未完成的请求next(); // 继续路由切换
});export default router;
3. 在组件中发起请求

在组件中正常发起 axios 请求,不需要额外的处理。每次请求都会通过 axios 封装自动附加 CancelToken,并在路由切换时通过 cancelPendingRequests 自动取消。

// src/views/Home.vue
<template><div><h1>Home</h1><p>{{ data }}</p></div>
</template><script>
import service from '@/utils/request';export default {data() {return {data: null,};},mounted() {this.fetchData();},methods: {async fetchData() {try {const response = await service.get('/api/home');this.data = response.data;} catch (error) {console.error(error);}},},
};
</script>

4. 页面级取消请求

有时我们只需要在页面组件内部取消请求,比如当用户离开页面时取消当前页面的请求,这时可以使用组件的 beforeRouteLeave 钩子。

// src/views/About.vue
<template><div><h1>About</h1><p>{{ data }}</p></div>
</template><script>
import service from '@/utils/request';
import { ref } from 'vue';export default {setup() {const data = ref(null);let requestSource = null;const fetchData = async () => {requestSource = service.CancelToken.source();try {const response = await service.get('/api/about', {cancelToken: requestSource.token,});data.value = response.data;} catch (error) {if (axios.isCancel(error)) {console.log('请求被取消');} else {console.error(error);}}};return { data, fetchData };},mounted() {this.fetchData();},beforeRouteLeave(to, from, next) {if (this.requestSource) {this.requestSource.cancel('页面离开取消请求');}next();},
};
</script>

总结

  • 全局取消:通过在 vue-routerbeforeEach 守卫中调用 cancelPendingRequests,每次路由切换时都会取消未完成的请求,避免页面切换后无用的网络请求消耗。
  • 局部取消:在页面组件内部使用 beforeRouteLeave 钩子取消单个页面的请求,确保当用户离开页面时及时中止未完成的请求。
  • 防止重复请求:通过对请求进行唯一标识,并在发起请求前检查是否有相同请求正在进行,可以防止重复发送相同的请求。

通过结合 vue-routeraxiosCancelToken,可以有效地管理请求的生命周期,确保用户体验的流畅性。

在实际开发中,前端项目可能会需要请求不同的服务地址(例如,不同的 API 网关、微服务等),而 AxiosbaseURL 是请求的默认根路径。如果项目中需要根据具体请求来动态配置不同的 baseURL,有几种方式可以处理:

常见解决方案

1. 在请求时动态指定 baseURL

可以根据不同的业务逻辑或接口,动态为每个请求指定 baseURLAxios 支持在发起请求时覆盖默认的 baseURL,通过为每个请求单独设置 baseURL 来实现多服务地址请求。

import axios from 'axios';// 默认 axios 实例
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // 默认的 baseURLtimeout: 10000, // 超时时间
});// 示例:根据业务逻辑或特定条件指定不同的 baseURL
export function fetchDataFromServiceA() {return service({url: '/serviceA/data',baseURL: 'https://api.serviceA.com', // 为这个请求动态设置 baseURLmethod: 'get',});
}export function fetchDataFromServiceB() {return service({url: '/serviceB/data',baseURL: 'https://api.serviceB.com', // 另一个服务的 baseURLmethod: 'get',});
}
2. 创建多个 Axios 实例

如果不同服务的 baseURL 是固定的,并且它们各自有独立的配置,那么可以为每个服务创建一个独立的 Axios 实例。这样可以对不同服务有不同的 baseURLheaders 或其他配置。

import axios from 'axios';// 服务A的 axios 实例
const serviceA = axios.create({baseURL: 'https://api.serviceA.com',timeout: 10000,
});// 服务B的 axios 实例
const serviceB = axios.create({baseURL: 'https://api.serviceB.com',timeout: 10000,
});// 使用 serviceA 发送请求
export function fetchServiceAData() {return serviceA.get('/data');
}// 使用 serviceB 发送请求
export function fetchServiceBData() {return serviceB.get('/data');
}

这种方式使得各个服务的配置更加独立清晰,有助于代码的可维护性。

3. 根据环境动态配置 baseURL

对于一些需要根据不同的环境(如开发、生产等)动态切换服务地址的需求,可以在配置文件中根据 NODE_ENV 来设定不同的 baseURL

// .env.development
VUE_APP_BASE_API=https://dev.api.com// .env.production
VUE_APP_BASE_API=https://prod.api.com

axios 的封装文件中读取环境变量:

import axios from 'axios';const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // 根据环境变量设置 baseURLtimeout: 10000,
});export default service;
4. 通过请求拦截器动态修改 baseURL

如果需要根据请求的特定条件(例如请求的路径、参数等)来动态设置不同的 baseURL,可以在 axios 的请求拦截器中根据条件修改 config.baseURL

import axios from 'axios';// 默认 axios 实例
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // 默认的 baseURLtimeout: 10000,
});// 请求拦截器 - 根据特定条件动态设置 baseURL
service.interceptors.request.use((config) => {if (config.url.includes('/serviceA')) {config.baseURL = 'https://api.serviceA.com'; // 动态切换到 serviceA 的 baseURL} else if (config.url.includes('/serviceB')) {config.baseURL = 'https://api.serviceB.com'; // 动态切换到 serviceB 的 baseURL}return config;},(error) => {return Promise.reject(error);}
);export default service;
5. 在组件中指定 baseURL

在组件中直接为特定的请求指定 baseURL,这也是一种灵活的方式,适用于只在特定组件内进行请求的情况。

<template><div><button @click="fetchData">获取数据</button></div>
</template><script>
import axios from 'axios';export default {methods: {fetchData() {axios({url: '/data',baseURL: 'https://api.serviceA.com', // 在组件中指定 baseURLmethod: 'get',}).then((response) => {console.log('数据:', response.data);}).catch((error) => {console.error('请求错误:', error);});},},
};
</script>

6. 根据 API 名称或者模块切换 baseURL

可以将 API 分模块管理,通过模块名自动选择对应的 baseURL。例如,可以根据模块名动态选择不同的 baseURL

const serviceMap = {serviceA: 'https://api.serviceA.com',serviceB: 'https://api.serviceB.com',
};export function request({ module, url, ...options }) {const service = axios.create({baseURL: serviceMap[module], // 动态选择 baseURLtimeout: 10000,});return service({ url, ...options });
}// 使用
request({module: 'serviceA',url: '/data',method: 'get',
}).then(response => {console.log(response.data);
});

总结

  1. 动态设置 baseURL:直接在请求中指定 baseURL,适用于小范围的不同服务地址请求。
  2. 多个 Axios 实例:为每个服务创建独立的 Axios 实例,适用于多个不同服务地址的项目,清晰明确。
  3. 环境变量切换:根据开发、生产环境自动配置不同的 baseURL
  4. 拦截器动态修改:通过请求拦截器动态修改 baseURL,适合复杂场景的需求。
  5. 模块化管理:根据模块名或者业务需求选择不同的 baseURL,可读性更高。

根据你的项目规模和需求,可以选择最适合的方式处理多 baseURL 问题。

加密解密方案

在前后端通信中,使用加密方案来保护数据的安全性是非常重要的。常见的加密方式通常有对称加密、非对称加密和哈希算法。以下是一些在 Axios 中常用的加密方案,结合前后端的使用场景以及如何在 Axios 请求中应用这些加密方式。

常见加密方式

1. 对称加密(Symmetric Encryption)

对称加密是指加密和解密使用相同的密钥。常见的对称加密算法有 AES(Advanced Encryption Standard)。在前后端通信中,可以使用对称加密对敏感信息进行加密,后端使用相同的密钥解密。

使用场景:

对称加密通常用于加密敏感数据(如用户密码、银行信息等)在传输中的保护。

在 Axios 中使用 AES 加密:
npm install crypto-js
import axios from 'axios';
import CryptoJS from 'crypto-js';const secretKey = 'your-secret-key'; // 需要和后端保持一致的密钥// 加密函数
function encryptData(data) {const ciphertext = CryptoJS.AES.encrypt(JSON.stringify(data), secretKey).toString();return ciphertext;
}// 解密函数(在后端实现,前端不需要)
function decryptData(ciphertext) {const bytes = CryptoJS.AES.decrypt(ciphertext, secretKey);const decryptedData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));return decryptedData;
}// 使用加密后的数据发送请求
axios.post('/api/encrypt', {data: encryptData({username: 'user1',password: 'mypassword',}),
}).then(response => {console.log('Response:', response.data);
}).catch(error => {console.error('Error:', error);
});

在这种情况下,前端对敏感数据进行 AES 加密,然后通过 Axios 发送给服务器,服务器在收到数据后用相同的密钥进行解密。

2. 非对称加密(Asymmetric Encryption)

非对称加密使用一对密钥:公钥和私钥。常见的非对称加密算法是 RSA。通常,前端使用公钥加密数据,后端使用私钥解密数据。非对称加密适用于加密少量数据,因为它的加密速度较慢。

使用场景:

非对称加密常用于需要高度安全性的数据传输,如敏感的身份验证信息、密钥交换等。

在 Axios 中使用 RSA 加密:
npm install node-forge
import axios from 'axios';
import forge from 'node-forge';// 从后端获取公钥
axios.get('/api/public-key').then(response => {const publicKey = response.data.publicKey;// 使用 RSA 公钥加密const encryptWithRSA = (data, publicKey) => {const rsa = forge.pki.publicKeyFromPem(publicKey);const encrypted = rsa.encrypt(forge.util.encodeUtf8(data));return forge.util.encode64(encrypted);};// 加密数据const encryptedData = encryptWithRSA(JSON.stringify({username: 'user1',password: 'mypassword',}), publicKey);// 发送加密后的数据axios.post('/api/encrypt', {data: encryptedData,}).then(response => {console.log('Response:', response.data);});
});

在这种场景下,前端获取后端的公钥后,用 RSA 加密敏感数据,发送给服务器。后端用私钥解密数据。

3. 哈希算法(Hashing)

哈希算法用于将任意长度的数据映射为固定长度的散列值。常见的哈希算法包括 MD5、SHA-256 等。哈希算法通常用于验证数据的完整性,例如校验文件是否被篡改或传输过程中是否损坏。

使用场景:

哈希函数常用于密码的加盐哈希存储,或通过签名验证请求的完整性(如 HMAC)。

在 Axios 中使用 SHA-256 进行数据签名:
npm install crypto-js
import axios from 'axios';
import CryptoJS from 'crypto-js';// 加盐哈希
function hashData(data, secret) {const hash = CryptoJS.HmacSHA256(data, secret);return hash.toString(CryptoJS.enc.Hex);
}// 创建要发送的数据
const data = JSON.stringify({username: 'user1',password: 'mypassword',
});// 生成签名
const secret = 'your-secret-key';
const signature = hashData(data, secret);// 发送带有签名的请求
axios.post('/api/verify', {data,signature, // 传递签名以验证完整性
}).then(response => {console.log('Response:', response.data);
});

这种方式确保请求在传输过程中没有被篡改,后端可以使用相同的密钥对接收到的数据进行哈希计算,并验证签名是否匹配。

4. 混合加密

混合加密是对称加密和非对称加密的结合,通常用于提高安全性和效率。在实际应用中,通常会使用 RSA 非对称加密来加密 AES 对称加密的密钥,而数据则使用 AES 加密,这样可以兼顾效率和安全性。

使用场景:

混合加密常用于需要传输大量数据但仍需要高度安全性的场景,特别是前端生成随机的对称密钥,用 RSA 加密这个密钥后传递给后端。

实现混合加密:
import axios from 'axios';
import CryptoJS from 'crypto-js';
import forge from 'node-forge';// 使用 AES 生成随机密钥
function generateAESKey() {return CryptoJS.lib.WordArray.random(16).toString();
}// AES 加密数据
function encryptData(data, aesKey) {return CryptoJS.AES.encrypt(data, aesKey).toString();
}// RSA 公钥加密 AES 密钥
function encryptAESKeyWithRSA(aesKey, publicKey) {const rsa = forge.pki.publicKeyFromPem(publicKey);const encrypted = rsa.encrypt(forge.util.encodeUtf8(aesKey));return forge.util.encode64(encrypted);
}// 混合加密过程
axios.get('/api/public-key').then(response => {const publicKey = response.data.publicKey;const aesKey = generateAESKey();const encryptedData = encryptData(JSON.stringify({username: 'user1',password: 'mypassword',}), aesKey);const encryptedAESKey = encryptAESKeyWithRSA(aesKey, publicKey);// 发送加密的数据和加密的 AES 密钥axios.post('/api/encrypt', {encryptedData,encryptedAESKey,}).then(response => {console.log('Response:', response.data);});
});

在这种情况下,前端使用 AES 加密实际数据,并使用 RSA 加密 AES 密钥。后端接收到加密的密钥和数据后,先用 RSA 私钥解密 AES 密钥,再用 AES 密钥解密数据。

重复请求的优化和请求取消

  1. 防止重复请求
    通过使用请求的唯一标识(例如 url + method)来管理请求,防止用户短时间内重复发送相同请求。可以在发送请求前检查是否有相同的请求正在进行,如果有则不发送新的请求。

  2. 取消请求
    可以结合 axiosCancelToken,在用户离开页面或切换操作时取消未完成的请求,避免浪费资源。

总结

  • 对称加密:如 AES,适用于加密传输的敏感数据。
  • 非对称加密:如 RSA,适用于密钥交换和少量敏感数据的加密。
  • 哈希算法:如 SHA-256,常用于数据完整性验证。
  • 混合加密:结合 AES 和 RSA,兼顾性能和安全性,常用于大数据加密。

通过这些加密方案,能够有效地保护前后端通信中的数据安全。

相关文章:

axios的使用

在 Vue 项目中&#xff0c;封装 Axios 并实现加密、重复请求优化、请求取消、页面切换时取消未完成的请求、以及区分上传和下载操作是非常常见的需求。下面将逐一讲解这些需求的实现方式。 1. Axios 的基本封装 首先&#xff0c;我们可以将 Axios 封装到一个服务层中&#xf…...

Ubuntu 使用命令克隆和恢复SD卡

因为平常我需要做很多张开发板的出货卡&#xff0c;测试卡&#xff0c;那么我需要将备份下来文件&#xff0c;方便后续管理&#xff0c;这里时候需要用到Ubuntu上面的命令来克隆镜像和恢复镜像到SD卡上 先查询自己的SD卡是在sdx&#xff0c;以我的为例子&#xff0c;为sdb 备…...

Java 小游戏《超级马里奥》

文章目录 一、效果展示二、代码编写1. 素材准备2. 创建窗口类3. 创建常量类4. 创建动作类5. 创建关卡类6. 创建障碍物类7. 创建马里奥类8. 编写程序入口 一、效果展示 二、代码编写 1. 素材准备 首先创建一个基本的 java 项目&#xff0c;并将本游戏需要用到的图片素材 image…...

go语言defer详解

什么是defer&#xff1f;为什么需要defer&#xff1f;怎样合理使用defer?defer进阶 defer的底层原理是什么&#xff1f;利用defer原理defer命令的拆解defer语句的参数闭包是什么&#xff1f;defer配合recover后记参考资料 什么是defer&#xff1f; defer是Go语言提供的一种用…...

【C语言】循环中断break

在循环使用过程中&#xff0c;可能遇到某些情况需要终止循环。比如按座位查找一位学生&#xff0c;循环查找&#xff0c;找到时可以直接停止。后续的循环将不再执行。 break;只跳出一层循环 例子中的素数判断&#xff0c;查找到根号n停止&#xff1a;一个合数等于两个数的乘积…...

centos ping能通但是wget超时-解决

问题截图&#xff1a; 域名解析地址为IPV6地址&#xff0c;建议您调整IPV4优先级之后&#xff0c;再尝试访问&#xff0c;请参考Linux系统IPv4/IPv6双栈接入优先使用IPv4设置&#xff1a;移动云帮助中心 实操截图&#xff1a;...

SDIO - DWC MSHC 电压切换和频率切换

背景 我们的sdio访问sd card过去一直跑在低频上&#xff0c;HS50M。前段时间给eMMc添加了HS200模式&#xff0c;eMMc的总线模式定义是这样的&#xff1a; 可以看到1.8V的IO 电压可以支持所有模式&#xff0c;我们过去的芯片&#xff0c;由硬件部门放到evb上&#xff0c;其IO …...

EI-CLIP 深度理解 PPT

系列文章目录 文章目录 系列文章目录 在电子商务产品的跨模态检索中&#xff0c;电子商务图像和电子商务语言都有许多独特的特点。如图所示&#xff0c;一个电子商务产品图片通常只包含一个简单的场景&#xff0c;有一个或两个前景物体和一个普通的背景。同时&#xff0c;电子商…...

leetcode力扣刷题系列——【最小元素和最大元素的最小平均值】

题目 你有一个初始为空的浮点数数组 averages。另给你一个包含 n 个整数的数组 nums&#xff0c;其中 n 为偶数。 你需要重复以下步骤 n / 2 次&#xff1a; 从 nums 中移除 最小 的元素 minElement 和 最大 的元素 maxElement。 将 (minElement maxElement) / 2 加入到 aver…...

【线性回归分析】:基于实验数据的模型构建与可视化

目录 线性回归分析&#xff1a;基于实验数据的模型构建与可视化 1. 数据准备 2. 构建线性回归模型 3. 可视化 数据分析的核心 构建预测模型 应用场景 预测模型中的挑战 结论 线性回归分析&#xff1a;基于实验数据的模型构建与可视化 在数据分析领域&#xff0c;线性…...

CountUp.js 实现数字增长动画 Vue

效果&#xff1a; 官网介绍 1. 安装 npm install --save countup.js2. 基本使用 // template <span ref"number1Ref"></span>// script const number1Ref ref<HTMLElement>() onMounted(() > {new CountUp(number1Ref.value!, 9999999).sta…...

设计模式大全

1. 策略模式 什么是策略模式&#xff1f; 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以互换。策略模式使得算法可以独立于使用它的客户端而变化。通过使用策略…...

redis IO多路复用机制

目录 一、五种 I/O 模型 1.阻塞IO&#xff08;Blocking IO&#xff09; 2.非阻塞IO&#xff08;Nonblocking IO&#xff09; 3.IO多路复用&#xff08;IO Multiplexing&#xff09; 通知的方式 select模式 poll模式 epoll模式 4.信号驱动IO&#xff08;Signal Driven …...

Oracle漏洞修复 19.3 补丁包 升级为19.22

1.场景描述 上周末2024-10-12日,服务器扫出漏洞,希望及时修复。其中,oracle的漏洞清单如下,总结了下,基本都是 Oracle Database Server 的 19.3 版本到 19.20 版本和 21.3 版本到 21.11 版本存在安全漏洞,即版本问题。如: Oracle Database Server 安全漏洞(CVE-2023-22…...

Q2=10 and Q2=1--PLB(Fig.4)

&#xff08;个人学习笔记&#xff0c;仅供参考&#xff09; import numpy as np from scipy.special import kv, erfc from scipy.integrate import dblquad import matplotlib.pyplot as plt import scipy.integrate as spi# Constants w 0.6198 g0_sq 21.5989 rho 0.782…...

sd卡挂载返回FR_NOT_READY等错误

前言 本文章主要是例举文件系统挂载sd卡时出现的一下问题总结。本人用的芯片是GDF103系列&#xff0c;最近项目要使用sd进行读取文件&#xff0c;因此查阅了资料进行开发。一开始是使用了SPI方式连接&#xff0c;例程是原子哥的stm32进行改的&#xff0c;但多次调试都是卡死在发…...

推荐一款超级实用的浏览器扩展程序!实时翻译网页,支持多种语言(带私活源码)

今天给大家分享的一款浏览器插件。 一、背景 在如今的信息时代&#xff0c;互联网已经成为了人们获取信息、交流和娱乐的重要平台&#xff0c;而随着全球化的不断深入和交流的加强&#xff0c;越来越多的人开始关注各国的文化、政治和经济&#xff0c;因此需要浏览不同语言的…...

manjaro kde 24 应该如何设置才能上网(2024-10-13亲测)

要在 Manjaro KDE 24 上设置网络连接&#xff0c;可以按照以下步骤进行设置&#xff0c;确保你能够连接到互联网&#xff1a; 是的&#xff0c;你可以尝试使用一个简单的自动修复脚本来解决 Manjaro KDE 中的网络连接问题。这个脚本将检查网络服务、重新启动 NetworkManager、…...

2024软件测试面试大全(答案+文档)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计&#xff0c;到…...

unity动态批处理

unity动态批处理 动态批处理要求和兼容性渲染管线兼容性 使用动态批处理网格的动态批处理限制动态生成几何体的动态批处理 动态批处理 动态批处理是一种绘制调用批处理方法&#xff0c;用于批处理移动的 GameObjects 以减少绘制调用。动态批处理在处理网格和 Unity 在运行时动…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...