QQ互联登录 CDN 接入
QQ 互联登录 SDK 用于在第三方网站中嵌入 QQ 登录。通过 CDN 外链引入后,SDK 挂载在全局变量 QQLogin 上,并在指定容器中渲染登录组件。组件支持扫码登录、PC QQ 快捷登录和账密登录。用户完成登录后,会携带互联票据跳转到回调地址。
脚本地址固定为 https://res.connect.qq.com/jssdk/index.js,始终指向最新版本。SDK 更新后无需修改接入代码即可生效。
前置条件
在 QQ 互联平台 创建应用,获取 appid,并配置网站回调域。redirect_uri 需落在已配置的回调域内。浏览器环境要求见文末「兼容性」。
快速接入
在页面中预留容器,再引入脚本并初始化:
<div id="qq-login-container" style="width: 320px; height: 480px;"></div>
<script src="https://res.connect.qq.com/jssdk/index.js"></script>
<script>
QQLogin
.init({
appid: '你的 appid',
redirect_uri: 'https://your-site.com/callback',
element: '#qq-login-container',
onMessage: function (event, payload) {
console.log(event, payload);
},
})
.show();
</script>
同一个页面不能重复调用 QQLogin.init。重复调用会被忽略并抛出错误。如需重新初始化,先调用 destroy() 销毁旧实例,再重新 init。
容器尺寸建议
登录组件会根据容器尺寸自适应布局:
- 最低尺寸 280 × 280:容器宽或高小于 280px 时,内容无法完整展示,容器内会出现滚动条。
- 380px 为大组件分界:宽和高都超过 380px 时,会展示尺寸稍大的登录组件(更大的二维码与字号)。
- 始终居中:无论容器尺寸如何,登录组件都会在容器内水平、垂直居中。
初始化配置
QQLogin.init(config) 的 config 字段:
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
appid | string | 是 | - | 互联应用 ID |
redirect_uri | string | 是 | - | 回调地址。无需自行 UrlEncode,SDK 会统一编码 |
element | HTMLElement | string | 是 | - | 挂载登录容器的 DOM 元素或选择器 |
onMessage | (event: string, payload: unknown) => void | 是 | - | 事件回调。SDK 抛出的事件都会透传到此函数,见「事件清单」 |
response_type | string | 否 | 'code' | 授权类型:'code' 或 'token' |
state | string | 否 | - | 用于防止 CSRF 的状态值。授权回调时原样返回,建议设置并校验 |
scope | string[] | 否 | - | 请求用户授权的 scope 列表 |
redirect_type | string | 否 | 'parent' | 登录成功后的跳转方式:'parent'(顶层窗口跳转)、'self'(登录组件内跳转) |
lang | string | 否 | 'zh_CN' | 语言:'zh_CN'、'zh_TW'、'en_US' |
color_theme | string | 否 | 'auto' | 颜色主题:'light'、'dark'、'auto'(跟随系统) |
登录成功后的回调
用户登录成功后,SDK 会将授权结果(code 或 token、state 等参数)拼接到 redirect_uri 上,再按 redirect_type 跳转:
'parent':父级窗口跳转。'self':登录组件 iframe 内跳转。
同时 SDK 会通过 onMessage 抛出 login:success 事件。
显示与隐藏
init 只负责创建并预加载登录组件,组件初始为隐藏。在合适的时机调用 show() 展示,调用 hide() 隐藏。显隐切换不会重载页面,组件内状态会保留:
<script>
qqLogin.show();
qqLogin.hide();
qqLogin.isVisible();
</script>
如果希望等登录组件加载完成后再展示,可在收到 app:page_loaded 后再调用 show()。见「QQLogin.init」。
销毁实例
组件卸载、页面离开或需要重新初始化时,调用 destroy() 移除登录组件与事件监听:
<script>
qqLogin.destroy();
</script>
API 参考
SDK 通过全局变量 QQLogin 使用。静态方法负责创建实例或生成授权地址,实例方法负责控制已创建的登录组件。
QQLogin.init(config)
创建登录实例,并在 config.element 指定的容器中加载登录组件。组件初始化后需调用 show() 展示。配置项见「初始化配置」。
<script>
var qqLogin = QQLogin.init({
appid: '101xxxxxx',
redirect_uri: 'https://your-site.com/callback',
element: '#qq-login-container',
onMessage: function (event, payload) {
if (event === 'app:page_loaded') {
qqLogin.show();
}
},
});
</script>
QQLogin.getAuthUrl(config)
不嵌入登录组件,只返回完整的 QQ 授权地址。接入方拿到地址后自行决定打开方式,例如当前窗口跳转或新开窗口。入参与 init 相同,但不需要 element 和 onMessage。
<script>
var url = QQLogin.getAuthUrl({
appid: '101xxxxxx',
redirect_uri: 'https://your-site.com/callback',
});
location.href = url;
</script>
QQLogin.version
SDK 版本号,字符串。
setConfig(patch)
不重载登录组件,在运行时热切换部分配置。需在收到 app:page_loaded 事件后调用。
可热切换的字段:lang、redirect_type、color_theme、onMessage。均为可选,只传需要变更的字段。
<script>
qqLogin.setConfig({
lang: 'en_US',
color_theme: 'dark',
});
</script>
涉及主题变更时,SDK 会抛出 app:set_theme 事件。
show()
展示登录组件。只切换显隐,不重载页面,组件内状态(如扫码进度)会保留。重复调用没有副作用。
<script>
qqLogin.show();
</script>
hide()
隐藏登录组件。
<script>
qqLogin.hide();
</script>
isVisible()
返回登录组件当前是否可见,布尔值。
<script>
qqLogin.isVisible();
</script>
destroy()
销毁实例,移除登录组件与事件监听。销毁后需要重新调用 init 创建新实例。
<script>
qqLogin.destroy();
</script>
事件清单
SDK 在登录流程的各个节点抛出事件,统一通过初始化时传入的 onMessage(event, payload) 回调透传。event 为事件名字符串,payload 为事件携带的参数对象。
<script>
var qqLogin = QQLogin.init({
appid: '101xxxxxx',
redirect_uri: 'https://your-site.com/callback',
element: '#qq-login-container',
onMessage: function (event, payload) {
if (event === 'login:success') {
// 登录成功
}
},
});
</script>
应用生命周期
app:page_loaded
登录页加载完成。
- payload:
{}(无参数) - 时机:登录页渲染完成。此后方可调用
setConfig热切换配置
app:page_ready
登录页进入可用状态。
- payload:
{}(无参数) - 时机:初始化完成、登录页可交互时抛出(已正常加载二维码),仅一次
- 互斥:若已抛出
app:page_error,则不再抛出此事件
app:page_error
登录页初始化时发生错误,导致不可用。
- payload:
| 字段 | 类型 | 说明 |
|---|---|---|
reason | string | 错误原因,见下表 |
reason 可能取值:
| 值 | 说明 |
|---|---|
'invalid_config' | OAuth 参数校验失败(缺 appid / redirect_uri 等) |
'qr_load_failed' | 二维码首次加载失败 |
'runtime_error' | 运行时脚本错误(未捕获异常 / Promise rejection / 渲染错误) |
- 时机:初始化阶段发生致命错误时抛出,仅一次
- 互斥:若已抛出
app:page_ready,则不再抛出此事件
app:set_theme
实际生效的颜色主题。
- payload:
| 字段 | 类型 | 说明 |
|---|---|---|
theme | 'light' | 'dark' | 当前实际生效的主题(auto 已解析为具体值) |
- 时机:初始主题应用后抛出一次;切换主题或
auto模式下系统主题变化时再次抛出
登录结果
login:success
登录成功。
- payload:
{}(无参数) - 时机:登录成功且授权流程完成后抛出。若用户拒绝授权,则不抛出该事件,停留在登录页
兼容性
登录页跑在互联侧的 iframe 里,SDK 跑在接入方页面里。两边的兼容范围分开计算。
登录页
登录页的最佳运行环境是 Chrome 49 及以上,或 Microsoft Edge 等其他现代浏览器。
登录页会根据运行环境切换构建版本,运行时最低兼容下限是 IE 10 和 Microsoft Edge IE 模式。
外链脚本
https://res.connect.qq.com/jssdk/index.js 没有无法 polyfill 的语法,运行时用到的 API 都在 IE 10 之内,接入方不需要再为 SDK 补 polyfill。
SDK 使用的 API 及兼容下限:
| API | 兼容下限 |
|---|---|
encodeURIComponent | 早于 IE 10 |
Object.prototype.hasOwnProperty | 早于 IE 10 |
Object.keys | IE 9 |
Array.isArray | IE 9 |
Array.prototype.join、Array.prototype.push | 早于 IE 10 |
document.createElement、Element.setAttribute、Node.appendChild、Node.removeChild、innerHTML、style.cssText | 早于 IE 10 |
document.querySelector | IE 8 |
window.addEventListener、window.removeEventListener | IE 9 |
window.postMessage(可传递对象) | IE 10 |
HTMLIFrameElement.contentWindow | 早于 IE 10 |
