最新要闻
- 当前快播:河北用上了无人驾驶农机:北斗加持 坐在屋里就把地给种了
- 今日要闻!奔驰、宝马、特斯拉相继取消收音机!广播公司担忧:有隐患
- 换机周期将创历史新高:长达43个月 你多久换一次?
- 波音、空客狂喜 印度将签史诗级飞机订单:一次买下500架
- 天天实时:创建全国首个ICU!我国重症医学奠基人陈德昌离世 享年90岁
- 【世界新要闻】2799元配酷睿i5!小米迷你主机将开启众筹 便宜900元条件公布
- 环球热门:小米13黑色版图赏:直屏直边手感秒杀iPhone 14!
- 真爱粉!有米粉花近万元抢了两台小米13
- 世界快资讯:好评率超99% 小米MIX Fold 2推出月光银配色 雷军:镜面效果令人惊叹
- 天天热点评!比RTX 4090便宜5000 AMD RX 7900系列显卡年底供货20万块:备货充足
- 小米13系列供不应求!线上已售罄 3999元起
- 环球即时:差价1000元!一文了解小米13和13 Pro区别
- 世界观察:NASA猎户座登月飞船成功返回地球:美国完成重返月球第一步
- 环球观天下!手机“毒瘤”微信终于修复!转发文件多次保存问题解决:不占空间了
- 天天微头条丨算了吧!电脑RGB光效好看不好玩
- 59岁李连杰晒照引网友围观 “功夫皇帝”定居国外略显苍老
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
短信+邮箱验证码登录
(相关资料图)
1、新增依赖
com.aliyun aliyun-java-sdk-core 4.1.0 org.springframework.boot spring-boot-starter-mail
2、前端示例
Login.vue
<script>import axios from "axios"export default { name: "Login", data() { const validateUsername = (rule, value, callback) => { if (value.length === 0) { callback(new Error("请输入正确的用户名")) } else { callback() } } const validatePassword = (rule, value, callback) => { if (value.length < 6) { callback(new Error("密码不能小于6位")) } else { callback() } } const validatePhone = (rule, value, callback) => { const reg = /^[1][3-9][0-9]{9}$/; if (value == "" || value == undefined || value == null) { callback(new Error("请输入手机号码")); } else { if ((!reg.test(value)) && value != "") { callback(new Error("请输入正确的手机号码")); } else { callback(); } } } return { loginForm: { username: "", password: "", key: "", captcha: "" }, phoneForm: { phoneNo: "", code: "" }, emailForm: { email: "", code: "" }, loginRules: { username: [{required: true, trigger: "blur", validator: validateUsername}], password: [{required: true, trigger: "blur", validator: validatePassword}], phoneNo: [{required: true, trigger: "blur", validator: validatePhone}], email: [{ required: true, type: "email", message: "请输入邮箱", trigger: "blur" }], captcha: [{ required: true, type: "string", message: "请输入验证码", trigger: "blur" }], code: [{ required: true, type: "string", message: "请输入验证码", trigger: "blur" }], pwd: [{ required: true, message: "创建密码", trigger: "blur" }, {pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/, message: "密码必须同时包含数字与字母,且长度为 8-20位"}], cpwd: [{ required: true, message: "确认密码", trigger: "blur" }, { validator: (rule, value, callback) => { if (value === "") { callback(new Error("请再次输入密码")) } else if (value !== this.ruleForm.pwd) { callback(new Error("两次输入密码不一致")) } else { callback() } }, trigger: "blur" }] }, statusMsg: "", loading: false, isDisable: false,// 验证码按钮禁用 codeLoading: false,// 验证码loading passwordType: "password", redirect: undefined, isRegist: true, imageSrc: "", verKey: "", showDialog: false } }, watch: { $route: { handler: function (route) { this.redirect = route.query && route.query.redirect }, immediate: true } }, created() { this.getCaptcha(); }, methods: { /*获取验证码*/ getCaptcha() { axios({ url: window.SITE_CONFIG["systemUrl"] + "/api/foreign/sms/get/captcha", method: "get", params: {} }).then(res => { console.log(res) let result = res.data.data this.loginForm.key = result.key; this.imageSrc = result.image; }).catch(err => { console.log(err) }) }, sendMsg: function (type) { if (type === 1) { const self = this let phonePass let timeRid if (timeRid) { return false } self.statusMsg = "" this.$refs["phoneForm"].validateField("phoneNo", (valid) => { phonePass = valid }) // 向后台API验证码发送 if (!phonePass) { self.codeLoading = true self.statusMsg = "验证码发送中..." let url = ""; let params = {}; axios({ url: window.SITE_CONFIG["systemUrl"] + "/api/foreign/sms/customer/sendMessageCode", method: "get", params: {phoneNo: self.phoneForm.phoneNo} }).then(res => { console.log(res) let result = res.data if (result.code == 200) { this.$message({ showClose: true, message: "发送成功,验证码有效期5分钟", type: "success" }) let count = 60 self.phoneForm.code = "" self.codeLoading = false self.isDisable = true self.statusMsg = `验证码已发送,${count--}秒后重新发送` timeRid = window.setInterval(function () { self.statusMsg = `验证码已发送,${count--}秒后重新发送` if (count <= 0) { window.clearInterval(timeRid) self.isDisable = false self.statusMsg = "" } }, 1000) } else { this.$message({ showClose: true, message: result.data, type: "warning" }) this.isDisable = false this.statusMsg = "" this.codeLoading = false } }).catch(err => { console.log(err) this.isDisable = false this.statusMsg = "" this.codeLoading = false console.log(err.data) }) } } if (type === 2) { const self = this let emailPass let timeRid if (timeRid) { return false } self.statusMsg = "" this.$refs["emailForm"].validateField("email", (valid) => { emailPass = valid }) // 向后台API验证码发送 if (!emailPass) { self.codeLoading = true self.statusMsg = "验证码发送中..." axios({ url: window.SITE_CONFIG["systemUrl"] + "/api/foreign/sms/customer/sendEmailMessage", method: "get", params: {email: self.emailForm.email} }).then(res => { console.log(res) let result = res.data if (result.code == 200) { this.$message({ showClose: true, message: "发送成功,验证码有效期5分钟", type: "success" }) let count = 60 self.emailForm.code = "" self.codeLoading = false self.isDisable = true self.statusMsg = `验证码已发送,${count--}秒后重新发送` timeRid = window.setInterval(function () { self.statusMsg = `验证码已发送,${count--}秒后重新发送` if (count <= 0) { window.clearInterval(timeRid) self.isDisable = false self.statusMsg = "" } }, 1000) } else { this.$message({ showClose: true, message: result.data, type: "warning" }) this.isDisable = false this.statusMsg = "" this.codeLoading = false } }).catch(err => { console.log(err) this.isDisable = false this.statusMsg = "" this.codeLoading = false console.log(err.data) }) } } }, showPwd() { if (this.passwordType === "password") { this.passwordType = "" } else { this.passwordType = "password" } this.$nextTick(() => { this.$refs.password.focus() }) }, handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true this.show = false this.$store.dispatch("user/login", this.loginForm).then(() => { this.$router.push({path: "/"}) this.loading = false this.show = true }).catch(() => { this.loading = false this.show = true this.getCaptcha() }) } else { console.log("操作异常") this.getCaptcha() return false } }) }, phoneLogin() { this.$refs.phoneForm.validate(valid => { if (valid) { this.loading = true this.show = false this.$store.dispatch("user/phoneLogin", this.phoneForm).then(() => { this.$router.push({path: "/"}) this.loading = false this.show = true }).catch(() => { this.loading = false this.show = true }) } else { console.log("操作异常") return false } }) }, emailLogin() { this.$refs.emailForm.validate(valid => { if (valid) { this.loading = true this.show = false this.$store.dispatch("user/emailLogin", this.emailForm).then(() => { this.$router.push({path: "/"}) this.loading = false this.show = true }).catch(() => { this.loading = false this.show = true }) } else { console.log("操作异常") return false } }) } }}</script>
3、后端示例
SmsController
import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/** * 短信验证码 * * @author my */@RestController@CrossOrigin@RequestMapping("/api/foreign/sms")public class SmsController { @Resource private SmsService smsService; /** * 发送短信验证码 * * @return */ @ApiOperation(value = "发送短信验证码", httpMethod = "GET", notes = "发送短信验证码") @GetMapping(value = "/customer/sendMessageCode") public String sendSmsMessage(@RequestParam(value = "phoneNo") String phoneNo) { return smsService.sendSmsMessage(phoneNo); } /** * 发送邮箱验证码 * * @return */ @ApiOperation(value = "发送邮箱验证码", httpMethod = "GET", notes = "发送邮箱验证码") @GetMapping(value = "/customer/sendEmailMessage") public String sendEmailMessage(@RequestParam(value = "email") String email) { return smsService.sendEmailMessage(email); } /** * 获取验证码 * * @return */ @ApiOperation(value = "获取验证码", httpMethod = "GET", notes = "获取验证码") @GetMapping(value = "/get/captcha") public String captcha() { return smsService.captcha(); }}
SmsService
import com.mxy.common.core.utils.DateUtils;import com.mxy.common.core.utils.RedisUtil;import com.mxy.common.core.utils.ServiceResult;import com.wf.captcha.SpecCaptcha;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.HashMap;import java.util.Map;import java.util.Random;import java.util.UUID;@Servicepublic class SmsService { @Value("${sms.max.limit}") private Integer maxLimit; @Value("${sms.sendError.content}") private String sendErrorContent; @Resource private RedisUtil redisUtil; @Resource private SmsSend smsSend; private static final String MESSAGE_LIMIT = "messager_limit:"; private static final String SEND_LIMIT = "sendmsg_limit_count:"; private static final String PHONE_NO = "message_phone_no:"; private static final String EMAIL_MESSAGE_LIMIT = "email_messager_limit:"; private static final String EMAIL_SEND_LIMIT = "email_sendmsg_limit_count:"; private static final String EMAIL_NO = "message_email_no:"; private static final String CAPTCHA_NO = "message_captcha_no:"; private Random random = new Random(); public String sendSmsMessage(String phoneNo) { // 非空检验 if (StringUtils.isEmpty(phoneNo)) { return ServiceResult.error("电话号码不能为空哦"); } String sendMsgKey = SEND_LIMIT + phoneNo; if (redisUtil.hasKey(sendMsgKey) && (int) redisUtil.get(sendMsgKey) > maxLimit) { return ServiceResult.error(sendErrorContent); } String phoneNoKey = PHONE_NO + phoneNo; // 如果验证码已发送 作废之前的验证码 if (redisUtil.hasKey(phoneNoKey)) { redisUtil.del(phoneNoKey); } String limitKey = MESSAGE_LIMIT + phoneNo; if (redisUtil.hasKey(limitKey)) { return ServiceResult.error("一分钟只能请求一次哦"); } // 随机生成6位验证码 String verifyCode = String.valueOf(random.nextInt(899999) + 100000); // 限制60秒只能生成一次验证码 redisUtil.set(limitKey, verifyCode, 60); // 短信验证码 5分钟失效 redisUtil.set(phoneNoKey, verifyCode, 300); int count = (int) (redisUtil.get(sendMsgKey) == null ? 0 : redisUtil.get(sendMsgKey)); // 计算当天23点59分59秒的秒数 long expireTime = DateUtils.getDifferentTimes(); // 当日0点过期 redisUtil.set(sendMsgKey, count + 1, expireTime); // 异步请求下发短信 smsSend.sendSmsMessage(phoneNo, verifyCode, 2); return ServiceResult.success("短信发送成功"); } public String sendEmailMessage(String email) { // 非空检验 if (StringUtils.isEmpty(email)) { return ServiceResult.error("邮箱地址不能为空哦"); } String sendMsgKey = EMAIL_SEND_LIMIT + email; if (redisUtil.hasKey(sendMsgKey) && (int) redisUtil.get(sendMsgKey) > maxLimit) { return ServiceResult.error(sendErrorContent); } String emailNoKey = EMAIL_NO + email; // 如果验证码已发送 作废之前的验证码 if (redisUtil.hasKey(emailNoKey)) { redisUtil.del(emailNoKey); } String limitKey = EMAIL_MESSAGE_LIMIT + email; if (redisUtil.hasKey(limitKey)) { return ServiceResult.error("一分钟只能请求一次哦"); } // 随机生成6位验证码 String verifyCode = String.valueOf(random.nextInt(899999) + 100000); // 限制60秒只能生成一次验证码 redisUtil.set(limitKey, verifyCode, 60); // 短信验证码 5分钟失效 redisUtil.set(emailNoKey, verifyCode, 300); int count = (int) (redisUtil.get(sendMsgKey) == null ? 0 : redisUtil.get(sendMsgKey)); // 计算当天23点59分59秒的秒数 long expireTime = DateUtils.getDifferentTimes(); // 当日0点过期 redisUtil.set(sendMsgKey, count + 1, expireTime); // 异步请求下发邮件 smsSend.sendEmailMessage(email, verifyCode); return ServiceResult.success("邮件发送成功"); } public String captcha() { SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4); String verCode = specCaptcha.text().toLowerCase(); String key = UUID.randomUUID().toString(); // 存入redis并设置过期时间为300秒 redisUtil.set(CAPTCHA_NO + key, verCode, 300); // 将key和base64返回给前端 Map map = new HashMap<>(); map.put("key", key); map.put("image", specCaptcha.toBase64()); return ServiceResult.success(map); }}
SmsSend
import com.aliyuncs.CommonRequest;import com.aliyuncs.CommonResponse;import com.aliyuncs.DefaultAcsClient;import com.aliyuncs.IAcsClient;import com.aliyuncs.profile.DefaultProfile;import com.mxy.common.core.entity.SysSmsSendLog;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.mail.MailException;import org.springframework.mail.SimpleMailMessage;import org.springframework.mail.javamail.JavaMailSender;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Component;import javax.annotation.Resource;/** * 短信发送 * * @author my */@Slf4j@Componentpublic class SmsSend { @Value("${sms.accessKeyId}") private String accessKeyId; @Value("${sms.secret}") private String secret; @Resource private JavaMailSender sender; /** * @description: 短信验证码发送 * @param: phoneNo-接收号码、verifyCode-验证码、type-短信模板类型(默认通用模板)(1-注册、2-登录、0-通用) * 签名说明: * 个人日常博客 * 模板说明: * 通用模板:SMS_25073XXXX 您的验证码${code},该验证码5分钟内有效,请勿泄漏于他人! * 登录验证码模板:SMS_25073XXXX 验证码为:${code},您正在登录,若非本人操作,请勿泄露。 * 注册验证码模板:SMS_25075XXXX 您正在申请手机注册,验证码为:${code},5分钟内有效! **/ @Async("threadPoolTaskExecutor") public void sendSmsMessage(String phoneNo, String verifyCode, int type) { DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret); IAcsClient client = new DefaultAcsClient(profile); // 组装请求对象 CommonRequest request = new CommonRequest(); // 短信API产品域名(接口地址固定,无需修改) request.setDomain("dysmsapi.aliyuncs.com"); request.setVersion("2017-05-25"); request.setAction("SendSms"); request.putQueryParameter("RegionId", "cn-hangzhou"); // 接收号码 request.putQueryParameter("PhoneNumbers", phoneNo); // 短信签名 request.putQueryParameter("SignName", "个人日常博客"); // 短信模板 String smsTemplate = ""; switch (type) { case 1: request.putQueryParameter("TemplateCode", "SMS_25075XXXX"); smsTemplate = "【个人日常博客】您正在申请手机注册,验证码为:" + verifyCode + ",5分钟内有效!"; break; case 2: request.putQueryParameter("TemplateCode", "SMS_25073XXXX"); smsTemplate = "【个人日常博客】验证码为:" + verifyCode + ",您正在登录,若非本人操作,请勿泄露。"; break; default: request.putQueryParameter("TemplateCode", "SMS_25073XXXX"); smsTemplate = "【个人日常博客】您的验证码" + verifyCode + ",该验证码5分钟内有效,请勿泄漏于他人!"; break; } // 验证码 request.putQueryParameter("TemplateParam", "{code:" + verifyCode + "}"); try { CommonResponse response = client.getCommonResponse(request); // 记录发送记录,可忽略 SysSmsSendLog sendLog = new SysSmsSendLog(); sendLog.setPhone(phoneNo); sendLog.setRequest(smsTemplate); sendLog.setResponse(String.valueOf(response.getData())); sendLog.insert(); log.info(phoneNo + "短信发送:" + response.getData()); } catch (Exception e) { e.printStackTrace(); log.info(phoneNo + "短信发送失败:" + e.getMessage()); } } @Async("threadPoolTaskExecutor") public void sendEmailMessage(String email, String verifyCode) { try { SimpleMailMessage mailMessage = new SimpleMailMessage(); mailMessage.setFrom("you.email@qq.com"); mailMessage.setTo(email); mailMessage.setSubject("个人日常博客验证码"); mailMessage.setText("您的验证码" + verifyCode + ",该验证码5分钟内有效,请勿泄漏于他人!"); sender.send(mailMessage); SysSmsSendLog sendLog = new SysSmsSendLog(); sendLog.setPhone(email); sendLog.setRequest(mailMessage.getText()); sendLog.setResponse("OK"); log.info(email + "->邮件发送:" + mailMessage.getText()); sendLog.insert(); } catch (MailException e) { e.printStackTrace(); log.info(email + "邮件发送失败:" + e.getMessage()); } }}
工具类
DateUtils
/** * 计算当天23点59分59秒的秒数 */ public static Long getDifferentTimes() { //计算当前时间到0点的秒数 Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 1); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000; }
RedisUtil
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.CollectionUtils;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;/** * Redis工具类 * * @author my * @date 2022-02-10 */@Componentpublic final class RedisUtil { @Autowired private RedisTemplate redisTemplate; /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存获取 * * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } }}
配置文件
application.yml
# 配置-emailspring: mail: host: smtp.qq.com # 发送邮件的服务器地址 username: you.email@qq.com # 开启 IMAP/SMTP服务 的qq邮箱的账号 password: xxxxxxxxxxxx # 开启 IMAP/SMTP服务 获得的授权码 default-encoding: UTF-8# 阿里云短信秘钥sms: accessKeyId: xxxxxxxxxxxx secret: xxxxxxxxxxxx max: limit: 10 sendError: content: 当日的获取验证码次数已用尽,请联系管理员解除限制。
-
今亮点!go-dongle 0.2.1 版本发布,一个轻量级、语义化的 golang 编码解码、加密解密库
dongle是一个轻量级、语义化、对开发者友好的Golang编码解码和加密解密库Dongle已被awesome-go收录,如果...
来源: 短信+邮箱验证码登录
今亮点!go-dongle 0.2.1 版本发布,一个轻量级、语义化的 golang 编码解码、加密解密库
当前快播:河北用上了无人驾驶农机:北斗加持 坐在屋里就把地给种了
今日要闻!奔驰、宝马、特斯拉相继取消收音机!广播公司担忧:有隐患
换机周期将创历史新高:长达43个月 你多久换一次?
波音、空客狂喜 印度将签史诗级飞机订单:一次买下500架
天天实时:创建全国首个ICU!我国重症医学奠基人陈德昌离世 享年90岁
【当前独家】公司产品太多了,怎么实现一次登录产品互通?
【世界新要闻】2799元配酷睿i5!小米迷你主机将开启众筹 便宜900元条件公布
环球热门:小米13黑色版图赏:直屏直边手感秒杀iPhone 14!
真爱粉!有米粉花近万元抢了两台小米13
世界快资讯:好评率超99% 小米MIX Fold 2推出月光银配色 雷军:镜面效果令人惊叹
天天热点评!比RTX 4090便宜5000 AMD RX 7900系列显卡年底供货20万块:备货充足
小米13系列供不应求!线上已售罄 3999元起
环球即时:差价1000元!一文了解小米13和13 Pro区别
世界观察:NASA猎户座登月飞船成功返回地球:美国完成重返月球第一步
环球观天下!手机“毒瘤”微信终于修复!转发文件多次保存问题解决:不占空间了
天天微头条丨算了吧!电脑RGB光效好看不好玩
59岁李连杰晒照引网友围观 “功夫皇帝”定居国外略显苍老
世界看热讯:Git从入门到实战
Python 基于xml.etree.ElementTree实现XML对比
天天微资讯!飞链云智能机器人-基于ChatGPT的有趣问答
穷人入侵TikTok直播间:躺着就能赚钱 真爽
焦点热讯:为了帮梅西赢球 我敲了一晚上的电子木鱼
环球速递!2022贺岁档总票房突破4亿!《阿凡达2》势不可挡 最快破亿
GPU CPU向量加法时间测试
快播:雷军运气爆棚:在小米手机官方活动 中奖一台小米13
世界资讯:小米音质最好智能音箱!小米Sound Pro开箱图赏
Windows OpenGL 图像透明度调节
焦点热文:异步批处理教程
小米首款万兆路由发布:1799元
天天速递!只要699元!小米旗舰降噪耳机Buds 4发布:HiFi音质
小米8款新品价格汇总:3999元的小米13爱不爱?
全球新资讯:雷军:只有两家做双尺寸双高端 一家是苹果 一家是小米
小米13正式亮相:金属直边 继续对标iPhone!
今亮点!3999元起!小米13正式发布:黄金尺寸小屏、满血徕卡镜头
不涨价 小米13价格良心了:顶配12+512GB还便宜200元
全球微动态丨小米13 Pro正式亮相:中框仅仅3.2毫米!科技纳米皮手感无敌
焦点消息!ELK+FileBeat日志分析系统
快看点丨差错控制
全球信息:Intel显卡驱动即将大更新!DX9、DX11老游戏有惊喜
环球快资讯:MIUI 14“剃刀计划”砍向应用臃肿:微信文件重复存储问题终于解决
全球快看点丨全新界面 系统大幅精简!MIUI 14正式发布
【世界聚看点】使webworker中支持使用import导入模块——threads.js
世界速看:说人话系列:DOM(Document Object Mode)究竟是怎么来的呢?
环球快报:俞敏洪称不敢进高档美发店:一顿好酒肉没有了 心疼
当前热点-达尔文错了?螃蟹竟在地球上出现了5次
全球新资讯:时间轮 (史上最全)
【天天聚看点】雷军晒小米13生产过程 由小米智能工厂全自动化装配
百事通!Intel独立显卡不做了?掌门人一句话 放心了!
长安深蓝SL03宣布涨价:预计上调2000元-8000元
环球快讯:沉船捞出165年前牛仔裤80万卖出:更有数不清的黄金
SpringMVC执行流程
全球快资讯丨任务调度系统-业务线资源隔离
天天微速讯:echarts设置暂无数据
老版本微博下线倒计时!新版已无法返回老版本
舒适降噪的天花板 索尼WH-1000XM5耳机跌破2000元
全球视点!苹果把果链撤出中国?难度可是地狱级的
天天滚动:SQLyog连接MYSQL时报错 Client does not support authentication protocol requested
世界快报:小米发布米家智能小厨宝7L S1:2000W速热、1年省电100度
播报:男子将手机改装成“偷拍神器”:摄像头改到耳机插孔 赚了30万
世界资讯:我迟早被这些AI绘画笑死
世界快报:买不到抗原检测试剂盒怎么办?不要慌
重点聚焦!Intel A750显卡新驱动性能实测:《CS:GO》帧数飙升79%
公众号附件怎么添加?还在用阅读原文的方式来添加吗,你已经落伍啦,现在大家都在用这个新方法,不仅方便还省事!
TabControl控件的简单使用-添加tab
【全球时快讯】Python爬虫实战,requests+xlwt模块,爬取螺蛳粉商品数据(附源码)
环球微速讯:Linux笔记03: Linux常用命令_3.3文件操作命令
新资讯:canvas分享
全球今头条!推特重推蓝V认证服务 苹果用户得多交3美元!马斯克也无能为力
每日焦点!三星S23 Ultra关键参数确定:首发高频版第二代骁龙8、祖传25W快充
童年记忆的黄桃罐头为啥突然火了?专家建议不要盲目囤
世界今头条!【2023最新B站评论爬虫】用python爬取上千条哔哩哔哩评论
【世界快播报】刘强东称新冠比感冒还轻微!王石也发声:只有鼻子不舒服 10天转阴
全球今亮点!再见C罗!C罗赛后痛哭:葡萄牙0-1摩洛哥 非洲球队首进4强
世界杯英法大战结束!法国2-1淘汰英格兰 晋级四强
中国市场已合资30年!又一车企资不抵债:销量暴跌
全球观速讯丨中国车企在俄罗斯销量飙升:市占率超1/3 主打中高端
每日消息!uniapp+unicloud开发微信小程序流程
焦点快看:清理备用内存 - 解决方案(备用内存占用过高且不自动释放)--九五小庞
天天日报丨Blazor和Vue对比学习(进阶.路由导航四):路由传参
王冰冰反向操作:戴摩洛哥围巾 希望葡萄牙获胜
今日看点:老黄怎么看?这张RTX 4090卖到了10万块 有钱也不一定买到:EVGA绝版货
东北市民网购宠物猪收到已冻僵 网友唏嘘:一个敢买一个敢发
【环球新要闻】从 695. 岛屿的最大面积 入手深度优先搜素DFS
快资讯丨用户重复注册分析-多线程事务中加锁引发的bug
【焦点热闻】PTA作业6-8电信系列总结
环球要闻:C#中的WebAPI
专为AR/VR打造!苹果全新操作系统名为xrOS:有专属应用商店 最早明年推出
全球看点:高校花2.4亿把教学课堂搬到了海上 网友羡慕不已
2022-6.824-Lab2:Raft
007爬虫之requests模块进阶
全球今日讯!攻防世界-unseping(序列化,Bash shell)
全球观速讯丨《暗黑破坏神4》赛季通行证需氪金购买 暴雪重申:不会充钱就变强
JavaScript:this指针
20点狂欢:淘宝每满200减30、天猫/京东每满300减40
厂家称黄桃罐头没药效 网友调侃:黄桃罐头为何成东北人疯狂膜拜的神物
全球看点:验证jenkins自动化部署
世界速读:首个进入太空的人类 宇航员加加林个人档案已解密:34岁死于空难
天天即时看!女生高铁录乐器考试被打断:工作人员知道情况后特意给换了地方