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

使用 163 邮箱实现 Spring Boot 邮箱验证码登录

使用 163 邮箱实现 Spring Boot 邮箱验证码登录

本文将详细介绍如何使用网易 163 邮箱作为 SMTP 邮件服务器,实现 Spring Boot 项目中的邮件验证码发送功能,并解决常见配置报错问题。


一、为什么需要邮箱授权码?

出于安全考虑,大多数邮箱服务商(如 163、QQ)都不允许直接使用登录密码进行第三方邮件发送
这时候你需要在邮箱设置中开启 SMTP服务 并生成 授权码 来代替密码使用。


二、163 邮箱如何开启第三方登录(获取授权码)

⚡ 步骤如下:

  1. 登录网页版 163 邮箱 → 点击【设置】
  2. 进入左侧【POP3/SMTP/IMAP】菜单
  3. 勾选【开启客户端授权密码功能】
  4. 在【授权密码管理】中点击【新建授权码】
  5. 填入备注(如:“SpringBoot邮件服务”)后生成授权码
  6. 备份授权码,用于项目配置

在这里插入图片描述
在这里插入图片描述


三、Spring Boot 项目中如何配置 163 邮箱发送邮件

✅ Maven 依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>

✅ application.properties 配置

spring.mail.host=smtp.163.com
spring.mail.port=465
spring.mail.username=你的邮箱@163.com
spring.mail.password=你的授权码
spring.mail.protocol=smtps
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.default-encoding=UTF-8

四、邮件发送核心代码

✅ 工具类 EmailSender.java

@Component
public class EmailSender {@Autowiredprivate JavaMailSender mailSender;@Value("${spring.mail.username}")private String fromEmail;public boolean send(String to, String code) {try {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(fromEmail);message.setTo(to);message.setSubject("【Boounion 登录验证码】");message.setText("您的验证码是:" + code + ",5分钟内有效,请勿泄露!");mailSender.send(message);return true;} catch (Exception e) {e.printStackTrace();return false;}}
}

五、常见错误及解决办法

错误信息原因解决方案
Got bad greeting from SMTP host... EOF未启用 SSL 或端口错误使用 port=465+配置 ssl.enable=true
Authentication failed使用了登录密码用授权码替换
Connection timed out网络被墙打开 465 端口 / 更换网络
Cannot send messagefrom 地址不一致setFrom() = spring.mail.username

六、邮件验证码防刷优化

使用 Redis 实现“60 秒内同邮箱不能重复发送验证码”的控制,避免恶意刷接口。

✅ UserService 代码示例:

public boolean isInCooldown(String email) {String key = "email_code_cooldown:" + email;return Boolean.TRUE.equals(redisTemplate.hasKey(key));
}public void markCooldown(String email) {redisTemplate.opsForValue().set("email_code_cooldown:" + email, "1", 60, TimeUnit.SECONDS);
}

✅ Controller 中判断逻辑:

if (userService.isInCooldown(email)) {return ResponseEntity.status(429).body("验证码已发送,请稍后再试");
}

在这里插入图片描述


七、邮件效果展示

验证码邮件示例:

您的验证码是:211337,5分钟内有效,请勿泄露!

在这里插入图片描述


八、总结

步骤状态
163 邮箱开通 SMTP
正确生成并使用授权码
Spring Boot 邮件配置无误
Redis 冷却控制防刷
邮件内容格式清晰

以上配置完成后,你就可以轻松实现一套完整、安全、可控的邮箱登录流程!


附录:完整文件(可自行补全代码)

Spring Boot 项目目录结构参考

src/main/java/org/example/
├── controller/
│   └── LoginController.java      # 登录与验证码相关接口
├── model/
│   └── User.java                 # 用户模型类
├── service/
│   └── UserService.java          # 登录逻辑与验证码缓存管理
├── util/
│   └── EmailSender.java          # 邮件发送工具类
└── Main.java                     # SpringBoot 启动类src/main/resources/
├── static/index.html             # 前端测试页面
└── application.properties        # 邮件 + Redis + DB 配置项

pom.xml ✅

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>BoounionERP</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><!-- Spring Boot 父项目 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.3</version><relativePath/></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- Spring Boot Web 模块(包含内嵌 Tomcat) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot mail 模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><!-- Spring Boot Redis 模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Spring Boot 开发工具模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency><!-- SQL Server JDBC 驱动 --><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>mssql-jdbc</artifactId><version>11.2.3.jre11</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

application.properties ✅

spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=BoounionDB;encrypt=true;trustServerCertificate=true
spring.datasource.username=sa
spring.datasource.password=bl123456
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.mail.host=smtp.163.com
spring.mail.port=465
spring.mail.username=你的邮箱
spring.mail.password=你的授权
spring.mail.protocol=smtps
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.default-encoding=UTF-8spring.data.redis.host=localhost
spring.data.redis.port=6379spring.jpa.hibernate.ddl-auto=none
server.port=8080

Main.java ✅

package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** ==================================================* This class Main is responsible for [功能描述].** @author darker* @version 1.0* ==================================================*/@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}
}

LoginController.java ✅

package org.example.controller;import org.example.model.User;
import org.example.service.UserService;
import org.example.util.EmailSender;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;
import java.util.Random;/*** ==================================================* This class LoginController is responsible for [功能描述].** @author darker* @version 1.0* ==================================================*/@RestController
@RequestMapping("/api")
public class LoginController {private final UserService userService;private final EmailSender emailSender;public LoginController(UserService userService, EmailSender emailSender) {this.userService = userService;this.emailSender = emailSender;}@PostMapping("/login")public ResponseEntity<Map<String, Object>> login(@RequestBody User user) {String result = userService.login(user);Map<String, Object> response = new HashMap<>();switch (result) {case "登录成功":// 拼接带参数的跳转地址String url = "https://www.baidu.com/s?wd=csdn";response.put("status", "success");response.put("redirectUrl", url);return ResponseEntity.ok(response);case "密码错误":response.put("status", "error");response.put("message", "密码错误");return ResponseEntity.status(401).body(response);case "用户不存在":response.put("status", "error");response.put("message", "用户不存在");return ResponseEntity.status(404).body(response);default:response.put("status", "error");response.put("message", "服务器异常");return ResponseEntity.status(500).body(response);}}@PostMapping("/login/code")public ResponseEntity<?> sendEmailCode(@RequestBody Map<String, String> payload) {String email = payload.get("email");if (email == null || email.isEmpty()) {return ResponseEntity.badRequest().body("邮箱不能为空");}if (!userService.isEmailRegistered(email)) {return ResponseEntity.status(404).body("该邮箱未注册");}// 检查是否在冷却期(例如60秒)if (userService.isInCooldown(email)) {return ResponseEntity.status(429).body("验证码已发送,请稍后再试");}// 生成6位验证码String code = String.format("%06d", new Random().nextInt(999999));boolean success = emailSender.send(email, code);if (success) {userService.saveEmailCode(email, code);userService.markCooldown(email);return ResponseEntity.ok("验证码发送成功");} else {return ResponseEntity.status(500).body("验证码发送失败");}}@PostMapping("/login/email")public ResponseEntity<?> loginWithEmailCode(@RequestBody Map<String, String> payload) {String email = payload.get("email");String code = payload.get("code");if (email == null || code == null) {return ResponseEntity.badRequest().body("邮箱或验证码不能为空");}if (!userService.isEmailRegistered(email)) {return ResponseEntity.status(404).body("该邮箱未注册");}if (!userService.verifyEmailCode(email, code)) {return ResponseEntity.status(401).body("验证码错误或已过期");}Map<String, Object> response = new HashMap<>();response.put("status", "success");response.put("message", "登录成功");return ResponseEntity.ok(response);}
}

User.java ✅

package org.example.model;/*** ==================================================* This class User is responsible for [功能描述].** @author darker* @version 1.0* ==================================================*/public class User {private String username;private String password;private String email;public User() {}public User(String username, String password) {this.username = username;this.password = password;}public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }
}

UserService.java ✅

package org.example.service;import org.example.model.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;import java.sql.*;/*** ==================================================* This class UserService is responsible for [功能描述].** @author darker* @version 1.0* ==================================================*/@Service
public class UserService {@Value("${spring.datasource.url}")private String dbUrl;@Value("${spring.datasource.username}")private String dbUser;@Value("${spring.datasource.password}")private String dbPassword;private static final long CODE_COOLDOWN_SECONDS = 60;private final StringRedisTemplate redisTemplate;public UserService(StringRedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}// 保存验证码到 Redis,5 分钟有效public void saveEmailCode(String email, String code) {String key = "email_code:" + email;redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);}// 验证验证码是否正确public boolean verifyEmailCode(String email, String code) {String key = "email_code:" + email;String cachedCode = redisTemplate.opsForValue().get(key);return code.equals(cachedCode);}// 判断邮箱是否注册public boolean isEmailRegistered(String email) {try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) {String sql = "SELECT COUNT(*) FROM Users WHERE email = ?";try (PreparedStatement stmt = conn.prepareStatement(sql)) {stmt.setString(1, email);try (ResultSet rs = stmt.executeQuery()) {rs.next();return rs.getInt(1) > 0;}}} catch (SQLException e) {e.printStackTrace();return false;}}public boolean isInCooldown(String email) {String key = "email_code_cooldown:" + email;return redisTemplate.hasKey(key);}public void markCooldown(String email) {String key = "email_code_cooldown:" + email;redisTemplate.opsForValue().set(key, "1", CODE_COOLDOWN_SECONDS, TimeUnit.SECONDS);}public String login(User user) {try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) {String checkUserSql = "SELECT password FROM Users WHERE username = ?";try (PreparedStatement stmt = conn.prepareStatement(checkUserSql)) {stmt.setString(1, user.getUsername());try (ResultSet rs = stmt.executeQuery()) {if (!rs.next()) {return "用户不存在";}String dbPassword = rs.getString("password");if (!dbPassword.equals(user.getPassword())) {return "密码错误";}return "登录成功";}}} catch (SQLException e) {e.printStackTrace();return "数据库错误";}}
}

EmailSender.java ✅

package org.example.util;import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;/*** ==================================================* This class EmailSender is responsible for [功能描述].** @author draker* @version 1.0* ==================================================*/@Component
public class EmailSender {private final JavaMailSender mailSender;@Value("${spring.mail.username}")private String fromEmail;public EmailSender(JavaMailSender mailSender) {this.mailSender = mailSender;}/*** 发送验证码邮件* @param to 收件人邮箱* @param code 验证码内容* @return true=发送成功,false=失败*/public boolean send(String to, String code) {try {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(fromEmail);message.setTo(to);message.setSubject("【Boounion 登录验证码】");message.setText("您的验证码是:" + code + ",5分钟内有效,请勿泄露!");mailSender.send(message);return true;} catch (Exception e) {System.err.println("邮件发送失败: " + e.getMessage());return false;}}
}

相关文章:

使用 163 邮箱实现 Spring Boot 邮箱验证码登录

使用 163 邮箱实现 Spring Boot 邮箱验证码登录 本文将详细介绍如何使用网易 163 邮箱作为 SMTP 邮件服务器&#xff0c;实现 Spring Boot 项目中的邮件验证码发送功能&#xff0c;并解决常见配置报错问题。 一、为什么需要邮箱授权码&#xff1f; 出于安全考虑&#xff0c;大…...

多模态大语言模型arxiv论文略读(六十八)

Image-of-Thought Prompting for Visual Reasoning Refinement in Multimodal Large Language Models ➡️ 论文标题&#xff1a;Image-of-Thought Prompting for Visual Reasoning Refinement in Multimodal Large Language Models ➡️ 论文作者&#xff1a;Qiji Zhou, Ruoc…...

APS「多目标平衡算法」如何破解效率与弹性的永恒博弈

APS&#xff08;高级计划与排程&#xff09;系统作为企业智能制造的核心引擎&#xff0c;通过整合需求预测、产能规划、生产调度、物料管理及数据分析等模块&#xff0c;构建了覆盖产品全生产流程的“感知-决策-执行-优化”闭环体系。 精准需求预测 APS系统通过构建需求特征数…...

网张实验操作-防火墙+NAT

实验目的 了解防火墙&#xff08;ENSP中的USG5500&#xff09;域间转发策略配置、NAT&#xff08;与路由器NAT配置命令不同&#xff09;配置。 网络拓扑 两个防火墙连接分别连接一个内网&#xff0c;中间通过路由器连接。配置NAT之后&#xff0c;内网PC可以ping公网&#xf…...

Spring 中常见的属性注入方式(XML配置文件)

在 Spring 中,XML 配置属性注入。 以下是几种常见的属性注入方式及其对应的简单示例代码。 1. 构造器注入 构造器注入是指通过类的构造函数来设置依赖项。 示例类: public class MyService {private final MyRepository myRepository;public MyService(MyRepository myRe…...

让 - 艾里克・德布尔与斯普林格出版公司:科技变革下的出版业探索

在数字化浪潮席卷全球的当下&#xff0c;传统出版行业面临着前所未有的挑战与机遇。《对话 CTO&#xff0c;驾驭高科技浪潮》的第 10 章聚焦于让 - 艾里克・德布尔&#xff08;Jean - Eric Debeure&#xff09;及其所在的斯普林格出版公司&#xff08;Springer Publishing Comp…...

【技巧】离线安装docker镜像的方法

回到目录 【技巧】离线安装docker镜像的方法 0. 为什么需要离线安装&#xff1f; 第一、 由于docker hub被墙&#xff0c;所以 拉取镜像需要配置国内镜像源 第二、有一些特殊行业服务器无法接入互联网&#xff0c;需要手工安装镜像 1. 可以正常拉取镜像服务器操作 服务器…...

05 web 自动化之 selenium 下拉鼠标键盘文件上传

文章目录 一、下拉框操作二、键盘操作三、鼠标操作四、日期控件五、滚动条操作六、文件上传七、定位windows窗口及窗口的元素总结&#xff1a;页面及元素常用操作 一、下拉框操作 from selenium.webdriver.support.select import Select import time from selenium.webdriver.…...

《Python星球日记》 第73天:情感分析与主题建模

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、情感分析基础1. 情感分析的应用场景2. 基于规则的方法3. 基于深度学习的方法3.1 使用LSTM进行情感分析3.2 基于BERT的情感分析二、主题建模…...

数学复习笔记 10

前言 我觉得数学的高分乃至满分属于那些&#xff0c;聪明&#xff0c;坚韧&#xff0c;勇敢&#xff0c;细致的人。我非常惭愧自己不是这样的人&#xff0c;我在生活中发现了这样的同学&#xff0c;和他们交流的时候我常常感到汗流浃背&#xff0c;因为他们非常扎实的基础知识…...

07 web 自动化之 Unittest 应用:测试报告装饰器断言

文章目录 一、常见的第三方库结合 unittest 生产 html 格式测试报告1、HtmlTestRunner2、BeatifulReport 二、装饰器 unittest.skip 强制跳过&条件跳过三、unittest的常用断言方法 一、常见的第三方库结合 unittest 生产 html 格式测试报告 1、HtmlTestRunner 官网下载 …...

Spring Cloud探索之旅:从零搭建微服务雏形 (Eureka, LoadBalancer 与 OpenFeign实战)

引言 大家好&#xff01;近期&#xff0c;我踏上了一段深入学习Spring Cloud构建微服务应用的旅程。我从项目初始化开始&#xff0c;逐步搭建了一个具备服务注册与发现、客户端负载均衡以及声明式服务调用功能的基础微服务系统。本文旨在记录这一阶段的核心学习内容与实践成果…...

9.2.高并发系统

目录 一、高并发系统设计原则 核心设计哲学 • CAP权衡&#xff1a;一致性、可用性、分区容错性的场景化选择 • BASE理论&#xff1a;最终一致性与柔性事务的落地策略 性能与扩展性准则 • 水平扩展 vs 垂直扩展&#xff1a;无状态服务与有状态服务的扩展策略 • 异步化设计…...

Apollo学习——planning模块(3)之planning_base

planning_component、planning_base、on_lane_planning 和 navi_planning 的关系 1. 模块关系总览 继承层次 PlanningComponent&#xff1a;Cyber RT 框架中的 入口组件&#xff0c;负责调度规划模块的输入输出和管理生命周期。PlanningBase&#xff1a;规划算法的 抽象基类&…...

当 AI 邂逅丝路:揭秘「丝路智旅」,用 RAG 重塑中阿文化旅游体验

目录 系统命名:丝路智旅 (Silk Road Intelligent Travel)系统概述系统架构设计系统功能模块技术选型:为何是它们?系统优势与特点未来展望与扩展总结在数字浪潮席卷全球的今天,古老的丝绸之路正在以一种全新的方式焕发生机。当深厚的文化底蕴遇上尖端的人工智能技术,会碰撞…...

18.Excel数据透视表:第1部分创建数据透视表

一 什么是数据透视表 通过万花筒可以用不同的方式査看里面画面图像&#xff0c;在excel中可以将数据透视表看作是对准数据的万花筒&#xff0c;用不同角度去观察数据&#xff0c;也可以旋转数据&#xff0c;对数据进行重新排列&#xff0c;对大量的数据可以快速的汇总和建立交叉…...

CSS AI 通义灵码 VSCode插件安装与功能详解

简介 在前端开发领域&#xff0c;页面调试一直是个繁琐的过程&#xff0c;而传统开发中美工与前端的对接也常常出现问题。如今&#xff0c;阿里云技术团队推出的通义灵码智能编码助手&#xff0c;为前端开发者带来了新的解决方案&#xff0c;让开发者可以像指挥者一样&#xf…...

每日c/c++题 备战蓝桥杯(P1002 [NOIP 2002 普及组] 过河卒)

洛谷P1002 [NOIP 2002 普及组] 过河卒 题解 题目描述 过河卒是一道经典的动态规划题目。题目大意是&#xff1a;一个卒子从棋盘左上角(0,0)出发&#xff0c;要走到右下角(n,m)&#xff0c;棋盘上有一个马在(x,y)位置&#xff0c;卒子不能经过马所在位置及其周围8个位置。求卒…...

【Linux网络】TCP全连接队列

TCP 相关实验 理解 listen 的第二个参数 基于刚才封装的 TcpSocket 实现以下测试代码对于服务器, listen 的第二个参数设置为 1, 并且不调用 accept测试代码链接 test_server.cc #include "tcp_socket.hpp"int main(int argc, char* argv[]) {if (argc ! 3) {pri…...

HTML 颜色全解析:从命名规则到 RGBA/HSL 值,附透明度设置与场景应用指南

一、HTML 颜色系统详解 HTML 中的颜色可以通过多种方式定义&#xff0c;包括颜色名称、RGB 值、十六进制值、HSL 值等&#xff0c;同时支持透明度调整。以下是详细分类及应用场景&#xff1a; 1. 颜色名称&#xff08;预定义关键字&#xff09; HTML 预定义了 140 个标准颜色名…...

蓝桥杯12届国B 完全日期

题目描述。 如果一个日期中年月日的各位数字之和是完全平方数&#xff0c;则称为一个完全日期。 例如&#xff1a;2021 年 6 月 5 日的各位数字之和为 20216516&#xff0c;而 16 是一个完全平方数&#xff0c;它是 4 的平方。所以 2021 年 6 月 5 日是一个完全日期。 例如&…...

深度剖析多模态大模型中的视频编码器算法

写在前面 随着多模态大型语言模型(MLLM)的兴起,AI 理解世界的能力从静态的文本和图像,进一步拓展到了动态的、包含丰富时空信息的视频。视频作为一种承载了动作、交互、场景变化和声音(虽然本文主要聚焦视觉部分)的复杂数据形式,为 MLLM 提供了理解真实世界动态和因果关…...

游戏引擎学习第282天:Z轴移动与摄像机运动

运行游戏&#xff0c;展示目前进展 我们目前正在进行一个游戏开发项目。昨天&#xff0c;我们实现了基于房间的角色移动系统&#xff0c;并且加入了摄像机的跟随滚动功能。这是我们首次进入“游戏逻辑设计”阶段&#xff0c;也就是说&#xff0c;我们开始构建游戏本身的行为和…...

C++中的std::allocator

C中的std::allocator 文章目录 C中的std::allocator1.std::allocator1.1C中的placement new 和operator new1.2一个custom allocator的实现1.3使用std::allocator_traits实现allocator 1.std::allocator C中的std::allocator默默工作在CSTL中的所有容器的内存分配上&#xff0…...

Git/GitLab日常使用的命令指南来了!

在 GitLab 中拉取并合并代码的常见流程是通过 Git 命令来完成的。以下是一个标准的 Git 工作流&#xff0c;适用于从远程仓库&#xff08;如 GitLab&#xff09;拉取代码、切换分支、合并更新等操作。 &#x1f310; 一、基础命令&#xff1a;拉取最新代码 # 拉取远程仓库的所…...

aws 实践创建policy + Role

今天Cyber 通过image 来创建EC2 的时候,要添加policy, 虽然是administrator 的role, 参考Cyber 提供的link: Imageshttps://docs.cyberark.com/pam-self-hosted/14.2/en/content/pas%20cloud/images.htm#Bring 1 Step1:...

[Java实战]Spring Boot 解决跨域问题(十四)

[Java实战]Spring Boot 解决跨域问题&#xff08;十四&#xff09; 一、CORS 问题背景 什么是跨域问题&#xff1f; 当浏览器通过 JavaScript 发起跨域请求&#xff08;不同协议、域名、端口&#xff09;时&#xff0c;会触发同源策略限制&#xff0c;导致请求被拦截。 示例场…...

【HarmonyOS 5】鸿蒙星闪NearLink详解

【HarmonyOS 5】鸿蒙星闪NearLink详解 一、前言 鸿蒙星闪NearLink Kit 是 HarmonyOS 提供的短距离通信服务&#xff0c;支持星闪设备间的连接、数据交互。例如&#xff0c;手机可作为中心设备与外围设备&#xff08;如鼠标、手写笔、智能家电、车钥匙等&#xff09;通过星闪进…...

Python高级进阶:Vim与Vi使用指南

李升伟 整理 在 Python 高级进阶中&#xff0c;使用 Vim 或 Vi 作为代码编辑器可以显著提升开发效率&#xff0c;尤其是在远程服务器开发或快速脚本编辑时。以下是关于它们在 Python 开发中的高级应用详解&#xff1a; 1. Vim/Vi 简介 Vi&#xff1a;经典的 Unix 文本编辑器…...

【Python】对象生命周期全解析

Python对象生命周期全解析 在Python中&#xff0c;一个对象从创建到销毁会经历一系列过程&#xff0c;理解这些过程对于编写高效、可靠的Python代码非常重要。下面我将详细讲解Python对象的完整生命周期。 1. 对象创建阶段 (1) 内存分配 当使用类实例化时(obj MyClass())&…...