优化了部分方法实现
This commit is contained in:
@@ -76,7 +76,7 @@ wxSDK({
|
|||||||
| `sdk` | string | `https://res.wx.qq.com/open/js/jweixin-1.6.0.js` | 否 | 微信 SDK URL |
|
| `sdk` | string | `https://res.wx.qq.com/open/js/jweixin-1.6.0.js` | 否 | 微信 SDK URL |
|
||||||
| `title` | string \| string[] | `['分享至朋友圈', '分享至好友']` | 否 | 分享标题 |
|
| `title` | string \| string[] | `['分享至朋友圈', '分享至好友']` | 否 | 分享标题 |
|
||||||
| `desc` | string | `'万事皆虚,万物皆允'` | 否 | 分享描述 |
|
| `desc` | string | `'万事皆虚,万物皆允'` | 否 | 分享描述 |
|
||||||
| `shareIcon` | string \| string[] | 网站图标 | 否 | 分享图标 URL |
|
| `shareIcon` | string \| string[] | 网站图标 | 否 | 分享图标 URL(如果没有使用该属性将自动抓取页面头部类型为icon的资源作为分享图) |
|
||||||
| `shareLinks` | string \| string[] | 当前页面 URL | 否 | 分享链接 |
|
| `shareLinks` | string \| string[] | 当前页面 URL | 否 | 分享链接 |
|
||||||
| `debug` | boolean | `false` | 否 | 启用调试模式 |
|
| `debug` | boolean | `false` | 否 | 启用调试模式 |
|
||||||
| `jsApiList` | string[] | `[]` | 否 | 微信 JS API 列表 |
|
| `jsApiList` | string[] | `[]` | 否 | 微信 JS API 列表 |
|
||||||
|
301
index.js
301
index.js
@@ -6,7 +6,8 @@
|
|||||||
const wxSDK = (options = {}) => {
|
const wxSDK = (options = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 环境检测
|
// 环境检测
|
||||||
const w = typeof window !== 'undefined' ? window : self
|
const globalThis = typeof global !== 'undefined' ? global : self
|
||||||
|
const w = typeof window !== 'undefined' ? window : globalThis
|
||||||
if (!w.document) {
|
if (!w.document) {
|
||||||
return reject(new Error('wxSDK只能在浏览器环境下使用'))
|
return reject(new Error('wxSDK只能在浏览器环境下使用'))
|
||||||
}
|
}
|
||||||
@@ -30,7 +31,7 @@ const wxSDK = (options = {}) => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并配置(深度合并回调函数)
|
// 深度合并配置
|
||||||
const config = {
|
const config = {
|
||||||
...defaultConfig,
|
...defaultConfig,
|
||||||
...options,
|
...options,
|
||||||
@@ -44,70 +45,110 @@ const wxSDK = (options = {}) => {
|
|||||||
|
|
||||||
// 参数校验
|
// 参数校验
|
||||||
if (!apiUrl) {
|
if (!apiUrl) {
|
||||||
return reject(new Error('apiUrl is required'))
|
return reject(new Error('apiUrl为必填参数'))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理分享图标(使用 let 声明)
|
// 处理分享图标
|
||||||
let { shareIcon } = config
|
let { shareIcon } = config
|
||||||
try {
|
try {
|
||||||
const favicon = document.querySelector('link[rel="shortcut icon"], link[rel="icon"]')
|
const favicon = document.querySelector('link[rel*="icon"]')
|
||||||
if (favicon && favicon.href) {
|
if (favicon && favicon.href) {
|
||||||
shareIcon = favicon.href
|
shareIcon = favicon.href
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Favicon detection failed:', e)
|
console.warn('网站图标检测失败:', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDK 加载管理
|
// 常量定义
|
||||||
const scriptId = 'wxShare'
|
const SCRIPT_ID = 'wxShareSDK'
|
||||||
let scriptTag = document.getElementById(scriptId)
|
const BASE_API_LIST = ['updateTimelineShareData', 'updateAppMessageShareData']
|
||||||
let loadTimeout
|
const DEFAULT_OPEN_TAGS = ['wx-open-launch-app']
|
||||||
|
|
||||||
|
// 清理资源
|
||||||
|
let scriptTag = document.getElementById(SCRIPT_ID)
|
||||||
|
let timeoutId
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
clearTimeout(loadTimeout)
|
clearTimeout(timeoutId)
|
||||||
if (scriptTag) {
|
if (scriptTag) {
|
||||||
scriptTag.onload = null
|
scriptTag.onload = null
|
||||||
scriptTag.onerror = null
|
scriptTag.onerror = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载微信SDK
|
||||||
const loadSDK = () => {
|
const loadSDK = () => {
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|
||||||
scriptTag = document.createElement('script')
|
scriptTag = document.createElement('script')
|
||||||
scriptTag.id = scriptId
|
scriptTag.id = SCRIPT_ID
|
||||||
scriptTag.src = sdk
|
scriptTag.src = sdk
|
||||||
scriptTag.async = true
|
scriptTag.async = true
|
||||||
scriptTag.defer = true
|
scriptTag.defer = true
|
||||||
|
|
||||||
// 超时处理
|
return new Promise((loadResolve, loadReject) => {
|
||||||
loadTimeout = setTimeout(() => {
|
// 加载超时处理
|
||||||
cleanup()
|
timeoutId = setTimeout(() => {
|
||||||
document.head.removeChild(scriptTag)
|
cleanup()
|
||||||
reject(new Error(`微信JSSDK加载超时 ${timeout}ms`))
|
document.head.removeChild(scriptTag)
|
||||||
}, timeout)
|
loadReject(new Error(`微信JSSDK加载超时 (${timeout}ms)`))
|
||||||
|
}, timeout)
|
||||||
|
|
||||||
scriptTag.onload = () => {
|
scriptTag.onload = () => {
|
||||||
cleanup()
|
cleanup()
|
||||||
initWeChat()
|
loadResolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptTag.onerror = err => {
|
scriptTag.onerror = err => {
|
||||||
cleanup()
|
cleanup()
|
||||||
document.head.removeChild(scriptTag)
|
document.head.removeChild(scriptTag)
|
||||||
reject(new Error('微信JSSDK加载错误'))
|
loadReject(new Error('微信JSSDK加载失败'))
|
||||||
}
|
}
|
||||||
|
|
||||||
document.head.appendChild(scriptTag)
|
document.head.appendChild(scriptTag)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信初始化
|
// 获取微信签名
|
||||||
const initWeChat = () => {
|
const fetchSignature = async () => {
|
||||||
if (!w.wx) {
|
const controller = new AbortController()
|
||||||
return reject(new Error('微信JSSDK加载不正确'))
|
const fetchTimeout = setTimeout(() => controller.abort(), timeout)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${apiUrl}${encodeURIComponent(w.location.href.split('#')[0])}`, {
|
||||||
|
signal: controller.signal,
|
||||||
|
})
|
||||||
|
|
||||||
|
clearTimeout(fetchTimeout)
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`网络请求失败 (${response.status})`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await response.json()
|
||||||
|
const { appId, timestamp, nonceStr, signature } = res || {}
|
||||||
|
|
||||||
|
if (!appId || !timestamp || !nonceStr || !signature) {
|
||||||
|
throw new Error('接口响应格式错误')
|
||||||
|
}
|
||||||
|
|
||||||
|
return { appId, timestamp, nonceStr, signature }
|
||||||
|
} catch (err) {
|
||||||
|
clearTimeout(fetchTimeout)
|
||||||
|
throw new Error(`签名接口请求错误: ${err.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配置微信分享
|
||||||
|
const configureWeChat = async () => {
|
||||||
|
if (!w.wx || typeof w.wx.config !== 'function') {
|
||||||
|
throw new Error('微信JSSDK未正确加载')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 参数处理
|
// 获取签名
|
||||||
|
const signatureData = await fetchSignature()
|
||||||
|
|
||||||
|
// 准备分享配置
|
||||||
const timelineConfig = {
|
const timelineConfig = {
|
||||||
title: Array.isArray(title) ? title[0] : title,
|
title: Array.isArray(title) ? title[0] : title,
|
||||||
link: Array.isArray(shareLinks) ? shareLinks[0] : shareLinks.split('#')[0],
|
link: Array.isArray(shareLinks) ? shareLinks[0] : shareLinks.split('#')[0],
|
||||||
@@ -121,119 +162,105 @@ const wxSDK = (options = {}) => {
|
|||||||
desc,
|
desc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// API 列表处理
|
// 合并API列表
|
||||||
const baseApiList = ['updateTimelineShareData', 'updateAppMessageShareData']
|
const fullApiList = [...new Set([...BASE_API_LIST, ...jsApiList])]
|
||||||
const fullApiList = [...new Set([...baseApiList, ...jsApiList])]
|
const fullOpenTagList = [...new Set([...DEFAULT_OPEN_TAGS, ...openTagList])]
|
||||||
const fullOpenTagList = ['wx-open-launch-app', ...openTagList]
|
|
||||||
|
|
||||||
// 获取签名
|
// 初始化微信配置
|
||||||
fetch(`${apiUrl}${w.location.href.split('#')[0]}`)
|
w.wx.config({
|
||||||
.then(response => {
|
debug,
|
||||||
if (!response.ok) {
|
...signatureData,
|
||||||
throw new Error(`网络请求失败 (${response.status})`)
|
jsApiList: fullApiList,
|
||||||
}
|
openTagList: fullOpenTagList,
|
||||||
return response.json()
|
})
|
||||||
})
|
|
||||||
.then(res => {
|
// 返回封装后的wx对象
|
||||||
const { appId, timestamp, nonceStr, signature } = res || {}
|
return new Promise((wxResolve, wxReject) => {
|
||||||
if (!appId || !timestamp || !nonceStr || !signature) {
|
w.wx.error(wxReject)
|
||||||
throw new Error('接口响应格式错误')
|
|
||||||
|
w.wx.ready(() => {
|
||||||
|
const shareOperations = []
|
||||||
|
|
||||||
|
// 配置朋友圈分享
|
||||||
|
if (w.wx.updateTimelineShareData) {
|
||||||
|
shareOperations.push(
|
||||||
|
new Promise(shareResolve => {
|
||||||
|
w.wx.updateTimelineShareData({
|
||||||
|
...timelineConfig,
|
||||||
|
success: () => {
|
||||||
|
callback.success?.('timeline')
|
||||||
|
shareResolve()
|
||||||
|
},
|
||||||
|
fail: err => {
|
||||||
|
callback.error?.(err)
|
||||||
|
shareResolve() // 不阻断流程
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信配置
|
// 配置好友分享
|
||||||
w.wx.config({
|
if (w.wx.updateAppMessageShareData) {
|
||||||
debug,
|
shareOperations.push(
|
||||||
appId,
|
new Promise(shareResolve => {
|
||||||
timestamp,
|
w.wx.updateAppMessageShareData({
|
||||||
nonceStr,
|
...messageConfig,
|
||||||
signature,
|
success: () => {
|
||||||
jsApiList: fullApiList,
|
callback.success?.('message')
|
||||||
openTagList: fullOpenTagList,
|
shareResolve()
|
||||||
})
|
},
|
||||||
|
fail: err => {
|
||||||
w.wx.error(err => {
|
callback.error?.(err)
|
||||||
callback.error?.(err)
|
shareResolve() // 不阻断流程
|
||||||
reject(err)
|
},
|
||||||
})
|
|
||||||
|
|
||||||
w.wx.ready(() => {
|
|
||||||
try {
|
|
||||||
const shareOperations = []
|
|
||||||
|
|
||||||
// 朋友圈分享
|
|
||||||
if (w.wx.updateTimelineShareData) {
|
|
||||||
shareOperations.push(
|
|
||||||
new Promise(shareResolve => {
|
|
||||||
w.wx.updateTimelineShareData({
|
|
||||||
...timelineConfig,
|
|
||||||
success: () => {
|
|
||||||
callback.success?.('timeline')
|
|
||||||
shareResolve()
|
|
||||||
},
|
|
||||||
fail: err => {
|
|
||||||
callback.error?.(err)
|
|
||||||
shareResolve() // 不阻断流程
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 好友分享
|
|
||||||
if (w.wx.updateAppMessageShareData) {
|
|
||||||
shareOperations.push(
|
|
||||||
new Promise(shareResolve => {
|
|
||||||
w.wx.updateAppMessageShareData({
|
|
||||||
...messageConfig,
|
|
||||||
success: () => {
|
|
||||||
callback.success?.('message')
|
|
||||||
shareResolve()
|
|
||||||
},
|
|
||||||
fail: err => {
|
|
||||||
callback.error?.(err)
|
|
||||||
shareResolve() // 不阻断流程
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 等待所有分享配置完成
|
|
||||||
Promise.all(shareOperations)
|
|
||||||
.then(() => {
|
|
||||||
callback.ready?.()
|
|
||||||
resolve(w.wx)
|
|
||||||
})
|
})
|
||||||
.catch(e => {
|
})
|
||||||
console.error('分享设置失败:', e)
|
)
|
||||||
callback.ready?.()
|
}
|
||||||
resolve(w.wx) // 仍返回wx对象
|
|
||||||
})
|
// 等待所有分享配置完成
|
||||||
} catch (e) {
|
Promise.all(shareOperations)
|
||||||
reject(e)
|
.then(() => {
|
||||||
}
|
callback.ready?.()
|
||||||
})
|
wxResolve(w.wx)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(e => {
|
||||||
reject(new Error(`签名接口请求错误: ${err.message}`))
|
console.error('分享设置部分失败:', e)
|
||||||
|
callback.ready?.()
|
||||||
|
wxResolve(w.wx) // 仍返回wx对象
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载SDK
|
// 主执行流程
|
||||||
if (typeof w.wx === 'object' && w.wx.config) {
|
const initialize = async () => {
|
||||||
// 已加载SDK
|
try {
|
||||||
initWeChat()
|
// 加载SDK(如果需要)
|
||||||
} else if (scriptTag) {
|
if (!w.wx || typeof w.wx.config !== 'function') {
|
||||||
// 正在加载中
|
if (scriptTag && scriptTag.parentNode) {
|
||||||
scriptTag.onload = initWeChat
|
// 等待正在加载的SDK
|
||||||
scriptTag.onerror = err => {
|
await new Promise((resolve, reject) => {
|
||||||
cleanup()
|
scriptTag.onload = resolve
|
||||||
reject(new Error('微信JSSDK加载失败'))
|
scriptTag.onerror = () => reject(new Error('SDK加载失败'))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await loadSDK()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配置微信功能
|
||||||
|
const wxInstance = await configureWeChat()
|
||||||
|
resolve(wxInstance)
|
||||||
|
} catch (err) {
|
||||||
|
callback.error?.(err)
|
||||||
|
reject(err)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 全新加载
|
|
||||||
loadSDK()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 启动初始化
|
||||||
|
initialize()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wxsdk-pure",
|
"name": "wxsdk-pure",
|
||||||
"version": "1.0.3",
|
"version": "1.0.4",
|
||||||
"description": "微信分享 SDK 封装",
|
"description": "微信分享 SDK 封装",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
Reference in New Issue
Block a user