登录通用解决方案 —— 第三方登录处理

server/2024/12/14 0:11:04/

目录

01: 前言

02: 第三方平台登录解决方案流程大解析

03: QQ 开放平台流程大解析              

04: QQ 登录对接流程:获取 QQ 用户信息

05: QQ 登录对接流程:跨页面信息传输

06: QQ 登录对接流程:认证是否已注册,完成 QQ 登录流程

07: 移动端 QQ 登录对接:触发吊起操作,完成移动端 QQ 登录 

08: 微信开放平台大解析

微信公众平台和微信开放平台的区别

微信开放平台账户注册

个人主体注册

企业主体注册 

微信开放平台应用注册

开发者资质认证

09: 对接微信扫码登录

10: 总结 


 

01: 前言

从本文章开始我们将要去完成各种第三方的功能。

首先我们要去处理的就是 第三方登录

        1. QQ 登录

        2. 微信登录

        第三方登录是平时开发中一个非常常见的功能。针对这种功能,我们需要进行哪些准备,对接时又有哪些坑在等着我们呢? 让我们拭目以待吧。

02: 第三方平台登录解决方案流程大解析

通常情况下,我们所说的第三方登录指的是:通过第三方 APP 进行登录。

这个第三方 APP 是如何与我们自己的应用进行关联的呢?如果大家不是很清楚,本小节将为你解答。

想要搞明白这个问题,首先需要清楚整个第三方登录的流程是如何进行的。

我们以**网第三方登录为例:

1. 点击第三方登录按钮。

2. 弹出一个小窗口,展示对应的二维码。

3. 手机打开对应的 APP 进行扫码之后,会跳转到 同意页面,同时浏览器端也会显示扫码成功。

4. 手机端操作同意登录之后,会出现两种情况:

        1. 当前用户已注册:

                1. 直接登录。

        2. 当前用户未注册:

                1. 执行注册功能。

                2. 注册成功即可登录。

在这样的一个流程之中,第三方 APP 和我们自己的应用,分别都做了什么事情呢?

同样,我们对照流程进行说明:

1. 点击第三方登录按钮:执行 window.open 方法,打开一个第三方指定的 URL 窗口,该地址会指向第三方登录的 URL,并且由第三方提供一个对应的 二维码

2. 弹出一个小窗口,展示对应二维码:此处展示的二维码,为上一步中第三方提供的二维码。

3. 手机打开对应的 APP 进行扫码之后,会跳转到 同意页面。同时浏览器端也会显示扫码成功。在第三方中会一直对该页面进行 轮询,配合第三方 APP 来判断是否扫码成功。

4. 手机端操作同意登录之后,会出现两种情况:在 APP 中同意之后,第三方会进行对应的跳转,跳转地址为你指定的地址。在该地址中可以获取到 第三方的用户信息,该信息即为第三方登录时要获取到的关键数据。

5. 至此,第三方操作完成。接下来需要进行本平台的登录判定。

        1. 该注册指的是 第三方用户 是否在本平台中进行了注册。

        2. 因为之前的所有操作中,我们拿到的是 第三方用户信息。 

        3. 该信息可以帮助我们直接显示用户的用户名(nickname)和头像。但是因为不包含关键信息(手机号、用户名 username、密码),所以我们无法使用该信息帮助用户直接登录。

        4. 所以我们需要判断当前用户是否在咱们自己的平台中完成了注册。

                1. 当前用户已注册:

                        1. 直接登录。

                2. 当前用户未注册:

                        1. 执行注册功能。

综上所述,我们想要完成第三方登录功能,共分为两个大的步骤:

1. 对接第三方平台,获取第三方平台的用户信息。

2. 使用该用户信息,完成本应用的注册。

03: QQ 开放平台流程大解析              

想要对接 QQ 登录,需要使用到 QQ 互联 平台。在该平台中:

1. 注册账户。

2. 认证开发者。

3. 注册应用。

整体流程如下:

1. 注册账户

        1. 点击登录按钮,进行扫码登录。 

        2. 进行扫码登录。

2. 进行开发者审核

        1. 点击顶部头像,进入开发者审核阶段。

        2. 开发者审核分为:公司接入(需要上传营业执照信息)个人接入(需要上传身份证信息)两种。

        3. 信息输入完成之后,点击下一步进行 邮箱验证

        4. 进入邮箱,访问链接。

        5. 信息注册成功。

        6. 点击 管理中心,此时账户应处于 个人开发者 审核中 状态。 

        7. 等待审核信息通过。

3. 创建网站应用(需要等待审核通过之后)

        1. 选择 网站应用,点击 创建应用

        2. 选择 创建网站应用

        3. 填写网站资料。填写完成后,点击 创建应用。

        4. 应用创建成功。

        5. 完善资料,填写网站信息。

                1. 回调地址常见问题及修改方法。

        6. 应用创建成功。点击 应用管理 可进入应用管理后台。

        7. 此时应用状态应该为 审核中。

        8. 点击 查看 按钮,选择 应用接口

        9. 此时 登录 功能应该为 已获取 状态。

        10. 点击 get_user_info 即可进入 API 文档

此时,应用创建成功之后,即可进行 QQ 登录对接。 

04: QQ 登录对接流程:获取 QQ 用户信息

对接 QQ 登录分为以下几步:

        1. 展示 QQ 登录二维码

        2. 获取用户信息

        3. 完成跨页面数据传输

        4. 认证是否已注册

        5. 完成 QQ 对接

1. 在 index.html 中,导入 QQ SDK。

<!-- QQ 登录 -->
<script type="text/javascript"  charset="utf-8"src="http://connect.qq.com/qc_jssdk.js"data-appid="APPID"data-redirecturi="REDIRECTURI"
></script>

 2. 创建 src/views/login-register/login/qq-login.vue 组件,作为 QQ 登录处理组件,并初始化对应样式和基础功能:

- src/views/login-register/login
- - qq-login.vue
// src/views/login-register/login/qq-login.vue<template><div><span id="qqLoginBtn" v-show="false"></span><m-svg-iconclass="w-4 cursor-pointer"name="qq"@click="onQQLogin"></m-svg-icon></div>
</template><script>
// QQ 登录的 URL
const QQ_LOGIN_URL ='https://graph.qq.com/oauth2.0/authorize?client_id=101998494&response_type=token&scope=all&redirect_uri=https%3A%2F%2Fimooc-front.lgdsunday.club%2Flogin'
</script><script setup>
import { onMounted } from 'vue'
import brodacast from './brodacast'
import { oauthLogin } from './oauth'
import { LOGIN_TYPE_QQ } from '@/constants'// QQ 登录挂起
onMounted(() => {QC.Login({btnId: 'qqLoginBtn' //插入按钮的节点id},// 登录成功之后的回调,但是需要注意,这个回调只会在《登录回调页面中被执行》// 登录存在缓存,登录成功一次之后,下次进入会自动重新登录// (即:触发该方法,所以我们应该在离开登录页面时,注销登录)(data, opts) => {console.log('QQ登录成功')// 1. 注销登录,否则在后续登录中会直接触发该回调QC.Login.signOut()// 2. 获取当前用户唯一标识,作为判断用户是否已注册的依据const accessToken = /access_token=((.*))&expires_in/.exec(window.location.hash)[1]// 3. 拼接请求对象const oauthObj = {nickname: data.nickname,figureurl_qq_2: data.figureurl_qq_2,accessToken}// 4. 完成跨页面传输brodacast.send(oauthObj)// 针对于 移动端而言:通过移动端触发 QQ 登录会展示三个页面,// 原页面、QQ 吊起页面、回调页面。// 并且移动端一个页面展示整屏内容,且无法直接通过 window.close() 关闭,// 所以在移动端中,我们需要在当前页面继续进行后续操作。oauthLogin(LOGIN_TYPE_QQ, oauthObj)// 5. 在 PC 端下,关闭第三方窗口window.close()})
})/*** 登录按钮事件*/
const onQQLogin = () => {openQQWindow()
}/*** 处理 QQ 登录视窗*/
const openQQWindow = async () => {window.open(QQ_LOGIN_URL,'oauth2Login_10609','height=525,width=585, toolbar=no, menubar=no, scrollbars=no, status=no, location=yes, resizable=yes')// 打开视窗之后开始等待brodacast.wait().then(async (oauthObj) => {// 登录成功,关闭通知brodacast.clear()// 执行登录操作oauthLogin(LOGIN_TYPE_QQ, oauthObj)})
}
</script>

05: QQ 登录对接流程:跨页面信息传输

想要实现跨页面信息传输,通常有两种方式:

1. BroadcastChannel:允许 同源 的不同浏览器窗口、Tab 页、Frame 或者 Frame 下的不同文档之间相互通信。但是会有兼容性问题,实测 Safari@15.3 无法使用。

2. localstorage + window.onstorage:通过 localStorage 进行 同源 的数据传输。用来处理 BroadcastChannel 不兼容的浏览器。

依据以上两个 API,我们实现对应的通讯模块:

1. 创建 src/views/login-register/login/broadcast.js 模块:

// 频道名
const LOGIN_SUCCESS_CHANNEL = 'LOGIN_SUCCESS_CHANNEL'// 官方声明 safari 支持 BroadcastChannel ,但是实测 15.3 的版本并不支持 😠,所以我们需要对其进行判定使用,在不支持 BroadcastChannel 的浏览器中,使用 localstorage
let broadcastChannel = null
if (window.BroadcastChannel) {broadcastChannel = new BroadcastChannel(LOGIN_SUCCESS_CHANNEL)
}/*** 等待 QQ 登录成功* 因为 QQ 登录会在一个新的窗口中进行,用户扫码登录成功之后会回调《新窗口的 QC.Login 第二参数 cb》,而不会回调到原页面。* 所以我们需要在《新窗口中通知到原页面》,所以就需要涉及到 JS 的跨页面通讯,而跨页面通讯指的主要就是《同源页面的通讯》* 同源页面的通讯方式有很多,我们这里主要介绍:* 1. BroadcastChannel  ->  https://developer.mozilla.org/zh-CN/docs/Web/API/BroadcastChannel* 2. window.onstorage:注意:该事件不在导致数据变化的当前页面触发*/
/*** 等待回调,它将返回一个 promise,并携带对应的数据*/
const wait = () => {return new Promise((resolve, reject) => {if (broadcastChannel) {// 触发 message 事件时的回调函数broadcastChannel.onmessage = async (event) => {// 改变 promise 状态resolve(event.data)}} else {// 触发 localStorage 的 setItem 事件时回调函数window.onstorage = (e) => {// 判断当前的事件名if (e.key === LOGIN_SUCCESS_CHANNEL) {// 改变 promise 状态resolve(JSON.parse(e.newValue))}}}})
}/*** 发送消息。* broadcastChannel:触发 message* localStorage:触发 setItem*/
const send = (data) => {if (broadcastChannel) {broadcastChannel.postMessage(data)} else {localStorage.setItem(LOGIN_SUCCESS_CHANNEL, JSON.stringify(data))}
}/*** 清除*/
const clear = () => {if (broadcastChannel) {broadcastChannel.close()broadcastChannel = null}localStorage.removeItem(LOGIN_SUCCESS_CHANNEL)
}export default {wait,send,clear
}

2. 在 src/views/login-register/login/qq-login.vue 中使用:

<script setup>
import brodacast from './brodacast'// QQ 登录挂起
onMounted(() => {QC.Login({btnId: 'qqLoginBtn' //插入按钮的节点id},// 登录成功之后的回调,但是需要注意,这个回调只会在《登录回调页面中被执行》(data, opts) => {// 1. 注销登录,否则在后续登录中会直接触发该回调// 2. 获取当前用户唯一标识,作为判断用户是否已注册的依据// 3. 拼接请求对象const oauthObj = {nickname: data.nickname,figureurl_qq_2: data.figureurl_qq_2,accessToken}// 4. 完成跨页面传输brodacast.send(oauthObj)// 针对于 移动端而言:通过移动端触发 QQ 登录会展示三个页面,// 原页面、QQ 吊起页面、回调页面。并且移动端一个页面展示整屏内容,// 且无法直接通过 window.close() 关闭,// 所以在移动端中,我们需要在当前页面继续进行后续操作。oauthLogin(LOGIN_TYPE_QQ, oauthObj)// 5. 在 PC 端下,关闭第三方窗口window.close()})
})/*** 处理 QQ 登录视窗*/
const openQQWindow = async () => {……// 打开视窗之后开始等待brodacast.wait().then(async (oauthObj) => {// 登录成功,关闭通知brodacast.clear()// 执行登录操作oauthLogin(LOGIN_TYPE_QQ, oauthObj)})
}
</script>

06: QQ 登录对接流程:认证是否已注册,完成 QQ 登录流程

有了数据之后,接下来就可以认证当前用户是否已注册,从而判断是否需要进入注册页面。

1. 创建 src/views/login-register/login/oauth.js 模块:

import store from '@/store'
import router from '@/router'
import { message } from '@/libs'
import { LOGIN_TYPE_OAUTH_NO_REGISTER_CODE } from '@/constants'/*** 第三方登录统一处理方法* @param {*} oauthType 登录方式* @param {*} oauthData 第三方数据*/
export const oauthLogin = async (oauthType, oauthData) => {// 触发登录操作。根据登录操作的返回 判断 当前用户是否已经注册。const code = await store.dispatch('user/login', {loginType: oauthType,...oauthData})// 返回  204 表示当前用户未注册,此时给用户一个提示,走注册页面if (code === LOGIN_TYPE_OAUTH_NO_REGISTER_CODE) {message('success', `欢迎您 ${oauthData.nickname},请创建您的账号`, 6000)// 进入注册页面,同时携带当前的第三方数据和注册标记router.push({path: '/register',query: {reqType: oauthType,...oauthData}})return}// 否则表示用户已注册,直接进入首页router.push('/')
}

2. src/store/modules/user.js 中:

    /*** 登录*/async login(context, payload) {const { password } = payloadconst data = await loginUser({...payload,password: password ? md5(password) : ''})// QQ 扫码登录,用户未注册if (data.code === LOGIN_TYPE_OAUTH_NO_REGISTER_CODE) {return data.code}context.commit('setToken', data.token)context.dispatch('profile')}

登录接口信息: 

 

    登录时也需要头像信息 figureurl_qq_2,这里没展示出来。 

3. src/views/login-register/register/index.vue 中:

/*** 触发注册*/
const route = useRoute()const onRegister = async () => {loading.value = truetry {const payload = {username: regForm.value.username,password: regForm.value.password}// 触发注册,携带第三方数据await store.dispatch('user/register', {...payload,...route.query})// 注册成功,触发登录await store.dispatch('user/login', {...payload,loginType: LOGIN_TYPE_USERNAME})} finally {loading.value = false}router.push('/')
}

注册接口信息: 

 

4. src/views/login-register/login/qq-login.vue 中:

……
// 执行登录操作
oauthLogin(LOGIN_TYPE_QQ, oauthObj)
……// 详细上下文代码 在上一小节中。

07: 移动端 QQ 登录对接:触发吊起操作,完成移动端 QQ 登录 

目前我们的 QQ 登录功能已经可以在 PC 端中正常使用了。

但是在移动端中进行访问,大家会发现,有一些问题。

出现这个问题的原因是因为:

        对于 移动端 而言,通过移动端触发 QQ 登录,会展示三个页面,原页面、QQ 吊起页面、回调页面。

        并且移动端一个页面占据整屏,无法直接通过 window.close() 关闭。

        因此,在移动端 我们需要在当前页面中,继续进行后续操作。

 据此,我们可以在 src/views/login-register/login/qq-login.vue 中执行以下代码:

// QQ 登录挂起
onMounted(() => {QC.Login({btnId: 'qqLoginBtn' //插入按钮的节点id},// 登录成功之后的回调,但是需要注意,这个回调只会在《登录回调页面中被执行》(data, opts) => {// 1. 注销登录,否则在后续登录中会直接触发该回调// 2. 获取当前用户唯一标识,作为判断用户是否已注册的依据// 3. 拼接请求对象// 4. 完成跨页面传输// 针对于 移动端而言:通过移动端触发 QQ 登录会展示三个页面,// 原页面、QQ 吊起页面、回调页面。// 并且移动端一个页面展示整屏内容,且无法直接通过 window.close() 关闭,// 所以在移动端中,我们需要在当前页面继续进行后续操作。oauthLogin(LOGIN_TYPE_QQ, oauthObj)// 5. 在 PC 端下,关闭第三方窗口})
})

        window.open() 打开的视窗,在移动端下会以满屏的形式展示。因此,在移动端下,没必要执着于回到原页面。可以在新打开的页面中触发“后续的登录操作”。

08: 微信开放平台大解析

搞定了 QQ 扫码登录之后,接下来我们来处理 微信扫码 登录。 

对于微信扫码登录而言,同样需要进行开放平台的注册。本小节将为大家讲解微信开发平台的注册流程。

整个讲解将会分为:

1. 微信公众平台与微信开放平台的区别。

2. 微信开放平台账户注册。

3. 微信开放平台应用注册。

4. 开发者资质认证。

微信公众平台和微信开放平台的区别

微信公众平台

地址:https://mp.weixin.qq.com

作用:用于管理、开发 微信公众号(包括订阅号、服务号、企业号),相当于微信公众号的后台运营、管理系统。

微信开放平台

地址:https://open.weixin.qq.com/ 

作用:主要面对移动应用、网站应用 开发者,为其提供微信登录、分享、支付等相关权限和服务。

微信开放平台账户注册

1. 进入 微信开放平台,点击账号注册(注意:此账号将同时应用到登录、分享、支付等微信第三方模块)。

2. 填写基本信息。

3. 登记主体信息 - 主体类型说明:

        1. 主体信息常用的分为:企业 和 个人。

        2. 其中企业又分为:企业 和 个体工商户。

        3. 三者之间的区别如下图所示:

 

个人主体注册

1. 登记主体信息

2. 扫码进行身份验证

3. 点击下一步、确认主体信息

企业主体注册 

1. 企业主体注册需要具备 企业营业执照信息。 

2. 填写信息,选择 验证方式。

3. 验证方式分为两种:

        1. 支付验证:免费,对公转账验证。

        2. 微信认证:300元审核费用。

4. 支付验证方式:填写对公账户信息。

5. 扫码确认管理员信息。

6. 最后确认主体信息即可。

7. 企业用户最终还需要进行支付验证,每个注册账号对应的25位收款账号不同。

微信开放平台应用注册

1. 账户注册通过之后,可进入 管理中心,选择 网站应用,点击 创建网站应用

2. 创建网站应用共分为三步:

        1. 填写基本信息。

        2. 填写网站信息。

        3. 提交成功。

3. 第一步:填写基本信息。

4. 填写基本信息时,需要下载并填写《网站信息登记表扫描件》。

5. 填写完成。

6. 点击下一步,进入 授权回调域 输入。(请填写开发需要的合法域名,用户使用微信账号登录后,只能回调至该域名下的页面)

7. 点击 提交审核。审核通过后,你才可以获得 AppID 和 AppSecret,来进行开发。

8. 审核通过(可能会需要进行多次修改)。

        1. 微信登录接口:可用。

        2. 微信支付接口:不可用,有坑。

开发者资质认证

应用审核通过之后,大家可以发现应用的 微信登录微信支付 功能处于 未获得 状态。如果想要获得,需要 申请开通。(需要交钱)

1. 点击 申请开通

2. 此时需要先进行开发者认证。

3. 点击 去认证

4. 此时会进入到 开发者资质认证页面,在此页面中大家可以看到,想要申请开发者认证,则需要交付 300元 认证费用。

5. 如果你当前需要支付此费用,则点击 现在申请

6. 之后会进入 协议声明 页面,点击 下一步

7. 填写企业信息。

        1. 填写企业资质信息。

        2. 填写对公账户信息。

        3. 认证联系人。

        4. 联系人验证。

        5. 点击下一步

8. 填写发票信息,点击下一步。

9. 确认发票信息无误,点击继续。

10. 支付审核费用。300元。

11. 支付成功之后,会得到对应的订单详情数据。

12. 同时会有对应的邮件通知。

13. 等待审核通过即可。

14. 等待审核的过程中,会有 微信客服 与你电话联系,请注意接听(通常会在当天)

15. 审核通过之后,状态会变为 已验证

16. 此时,返回应用详情,微信登录已获得 状态,微信支付未获得状态

到这里,整体的微信开放平台注册流程就已经全部讲解完。

09: 对接微信扫码登录

进入 微信登录对接官方文档

整个微信登录流程与 QQ 登录流程略有不同,分为以下几步:

1. 通过 微信登录前置数据获取 接口,获取登录数据(比如 appId)。

2. 根据获取到的数据,拼接得到 open url 地址。

3. 打开该地址,展示微信登录二维码。

4. 移动端微信扫码确定登录。

5. 从当前窗口中解析 window.location.search 得到用户的 code 数据。

6. 根据 appId、appSecret、code,通过接口获取用户的 access_token。

7. 根据 access_token 获取用户信息。

8. 通过用户信息触发 oauthLogin 方法。

接下来,我们根据以上分析,开发对应代码逻辑:

1. 创建 src/views/login-register/login/weixin-login.vue 组件。

<template><div @click="onWeiXinLogin"><m-svg-icon class="w-4 cursor-pointer" name="wexin"></m-svg-icon><div id="login_container"></div></div>
</template><script setup>
import { getWXLoginData, getWXLoginToken, getWXLoginUserInfo } from '@/api/sys'
import brodacast from './brodacast'
import { oauthLogin } from './oauth'
import { LOGIN_TYPE_WX } from '@/constants'/*** 微信登录成功之后的窗口数据解析*/
if (window.location.search) {const code = /code=((.*))&state/.exec(window.location.search)[1]if (code) {brodacast.send({code})// 关闭回调网页window.close()}
}/*** 触发微信登录*/
const onWeiXinLogin = async () => {// 1. 通过微信登录前置数据获取接口,获取登录数据const { appId, appSecret, redirectUri, scope, state } = await getWXLoginData()// 2. 根据获取到的数据,拼接得到 `open url` 地址window.open(`https://open.weixin.qq.com/connect/qrconnect?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`,'','height=525,width=585, toolbar=no, menubar=no, scrollbars=no, status=no, location=yes, resizable=yes')// 等待扫码登录成功通知brodacast.wait().then(async ({ code }) => {console.log('微信扫码登录成功')console.log(code)// 微信登录成功,关闭通知brodacast.clear()// 获取 AccessToken 和 openidconst { access_token, openid } = await getWXLoginToken(appId,appSecret,code)console.log('access_token, openid')console.log(access_token, openid)// 获取登录用户信息const { nickname, headimgurl } = await getWXLoginUserInfo(access_token,openid)console.log(nickname, headimgurl)// 执行登录操作oauthLogin(LOGIN_TYPE_WX, {openid,nickname,headimgurl})})
}
</script><style lang="scss" scoped></style>

10: 总结 

        至此,我们完成了 QQ 扫码登录、微信扫码登录、移动端下的 QQ 主动吊起登录。但是对于 移动端网页 微信APP 而言,我们不能在普通的 H5 下吊起微信 APP 触发登录。

        根据本文章的内容可以发现,整个第三方登录逻辑还是比较复杂的。特别是微信的第三方登录步骤更加繁琐。并且我们在调试的时候必须要在线上进行调试(测试环境),所以大家在企业开发时,需要有更大的耐心才可以。 


http://www.ppmy.cn/server/47924.html

相关文章

MT2083 屠龙勇者

思路&#xff1a; 跟上题类似&#xff0c;贪心策略&#xff1a;w从小到大排序&#xff0c;每个头找到第一个>d的w 代码&#xff1a; #include <bits/stdc.h> using namespace std; #define ll long long const int N 1e5 10; int n, m; int d[N]; int w[N]; int …

网络原理——TCP/IP--数据链路层,DNS

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 目录 数量链路层目的地址和原地址类型校验和 DNS 数量链路层 主要的协议是以太网协议.一个横跨数据链路层和 物理层的协议,既包含了数据链路层的内容, 也包含了⼀些物理层的内容 我们来了解一…

AndroidStudio中debug.keystore的创建和配置使用

1.如果没有debug.keystore,可以按照下面方法创建 首先在C:\Users\Admin\.android路径下打开cmd窗口 之后输入命令:keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 输入两次密码(密码不可见,打码处随便填写没关系) 2.在build…

50个常用的Docker命令及如何使用

这里整理了50个常用的Docker命令以及每个命令的使用方法。 docker version:显示Docker版本信息。 示例:docker version docker info:显示Docker系统信息。 示例:docker info docker pull <image>:从Docker Hub下载镜像。 示例:docker pull ubuntu docker run <i…

1.1 OpenCV随手简记(一)

OpenCV学习篇 OpenCV (Open Source Computer Vision Library) 是一个开源的计算机视觉库&#xff0c;它提供了大量的算法和函数&#xff0c;用于图像处理、计算机视觉和机器学习等领域。 1. OpenCV 简介 1.1 OpenCV 的起源和发展 OpenCV 项目始于 1999 年&#xff0c;由 In…

RabbitMQ 如何保证消息不丢失

开启消息确认机制&#xff1a; 在发布消息时&#xff0c;可以设置deliveryMode为2&#xff08;持久化&#xff09;&#xff0c;以确保消息不会因为RabbitMQ的崩溃而丢失。 使队列持久化&#xff1a; 通过设置durable为true&#xff0c;可以确保队列在RabbitMQ重启后依然存在。…

vue3组件传值---vue组件通过属性,事件和provide,inject进行传值

通过属性传值&#xff08;父传子&#xff09; vue的组件具有props自建属性&#xff08;自定义名称&#xff0c;类似于class&#xff0c;id的属性&#xff09;&#xff0c;通过这个属性&#xff0c;父组件可以向子组件传递参数&#xff0c;从而实现组件之间的信息传递&#xff0…

Java 基础面试300题 (261-290)

Java 基础面试300题 &#xff08;261-290&#xff09; 261.CompletableFuture.runAsync和CompletableFuture.supplyAsync方法有什么区别&#xff1f; 这两个方法都可用于异步运行代码。但两者之间有一些区别如下 &#xff1a; runAsync不返回结果&#xff0c;返回的是一个Com…