mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
194 lines
5.4 KiB
TypeScript
194 lines
5.4 KiB
TypeScript
import { registerAndGetData } from '@/plugins/data'
|
|
import { defineComponentMetadata } from '@/components/define'
|
|
import { isIframe, isNotHtml, matchPattern } from '@/core/utils'
|
|
import { useScopedConsole } from '@/core/utils/log'
|
|
|
|
const displayName = '网址参数清理'
|
|
const console = useScopedConsole(displayName)
|
|
const entry = async () => {
|
|
if (isNotHtml() || isIframe()) {
|
|
return
|
|
}
|
|
/* spell-checker: disable */
|
|
const builtInNoClean = ['videocard_series']
|
|
const [noClean] = registerAndGetData('urlParamsClean.noClean', builtInNoClean)
|
|
const builtInBlockParams = [
|
|
'spm_id_from',
|
|
'from_source',
|
|
'from_spmid',
|
|
'from',
|
|
'seid',
|
|
'share_source',
|
|
'share_medium',
|
|
'share_plat',
|
|
'share_tag',
|
|
'share_session_id',
|
|
'share_from',
|
|
'bbid',
|
|
'ts',
|
|
'timestamp',
|
|
'unique_k',
|
|
'rt',
|
|
'tdsourcetag',
|
|
'accept_quality',
|
|
'broadcast_type',
|
|
'current_qn',
|
|
'current_quality',
|
|
'playurl_h264',
|
|
'playurl_h265',
|
|
'quality_description',
|
|
'network',
|
|
'network_status',
|
|
'platform_network_status',
|
|
'p2p_type',
|
|
'referfrom',
|
|
'visit_id',
|
|
'bsource',
|
|
'spm',
|
|
'hotRank',
|
|
'-Arouter',
|
|
'vd_source',
|
|
'is_story_h5',
|
|
'buvid',
|
|
'plat_id',
|
|
'goFrom',
|
|
'jumpLinkType',
|
|
'hasBack',
|
|
'noTitleBar',
|
|
'msource',
|
|
'live_from',
|
|
'plat_id',
|
|
'extra_jump_from',
|
|
'subarea_rank',
|
|
'popular_rank',
|
|
'launch_id',
|
|
'spmid',
|
|
]
|
|
const [blockParams] = registerAndGetData('urlParamsClean.params', builtInBlockParams)
|
|
const builtInSiteSpecifiedParams = [
|
|
{
|
|
match: /\/\/www\.bilibili\.com\/audio\/(au[\d]+|mycollection)/,
|
|
param: 'type',
|
|
},
|
|
{
|
|
match: /\/\/live\.bilibili\.com\//,
|
|
param: 'session_id',
|
|
},
|
|
{
|
|
match: /\/\/live\.bilibili\.com\//,
|
|
param: 'is_room_feed',
|
|
},
|
|
{
|
|
match: /\/\/www\.bilibili\.com\/bangumi\//,
|
|
param: 'theme',
|
|
},
|
|
{
|
|
match: /\/\/www\.bilibili\.com\/video\//,
|
|
param: 'mid',
|
|
},
|
|
{
|
|
match: /\/\/www\.bilibili\.com\/video\//,
|
|
param: 'up_id',
|
|
},
|
|
{
|
|
match: /\/\/mall\.bilibili\.com\//,
|
|
param: 'noReffer',
|
|
},
|
|
]
|
|
/* spell-checker: enable */
|
|
const [siteSpecifiedParams] = registerAndGetData(
|
|
'urlParamsClean.siteSpecifiedParams',
|
|
builtInSiteSpecifiedParams,
|
|
)
|
|
const builtInTailingSlash: { match: string | RegExp }[] = []
|
|
const [tailingSlash] = registerAndGetData('urlParamsClean.tailingSlash', builtInTailingSlash)
|
|
|
|
const getCleanUrl = (originalUrl: string) => {
|
|
const url = new URL(originalUrl, location.origin)
|
|
const urlParams = [...new URLSearchParams(url.search).entries()].map(
|
|
([key, value]) => `${key}=${encodeURIComponent(value)}`,
|
|
)
|
|
if (urlParams.some(param => noClean.some(it => param.includes(it)))) {
|
|
return originalUrl
|
|
}
|
|
const filteredParams = urlParams.filter(p => {
|
|
if (blockParams.some(b => p.startsWith(`${b}=`))) {
|
|
return false
|
|
}
|
|
if (
|
|
siteSpecifiedParams.some(
|
|
({ match, param }) => document.URL.match(match) && p.startsWith(`${param}=`),
|
|
)
|
|
) {
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
const filteredParamsString = filteredParams.join('&')
|
|
tailingSlash.forEach(({ match }) => {
|
|
const pathName = url.pathname
|
|
if (matchPattern(pathName, match) && pathName.endsWith('/')) {
|
|
url.pathname = pathName.slice(0, pathName.length - 1)
|
|
}
|
|
})
|
|
const query = filteredParamsString ? `?${filteredParamsString}` : ''
|
|
url.search = query
|
|
return url.toString()
|
|
}
|
|
|
|
const createHistoryHook = (
|
|
original: (data: unknown, unused: string, url: string, ...restArgs: unknown[]) => void,
|
|
) => {
|
|
return function historyHook(
|
|
data: unknown,
|
|
unused: string,
|
|
url: string,
|
|
...restArgs: unknown[]
|
|
) {
|
|
if (url === undefined || url === null) {
|
|
return original.call(this, data, unused, url, ...restArgs)
|
|
}
|
|
const resolvedUrl = (() => {
|
|
try {
|
|
return new URL(url, location.origin + location.pathname).toString()
|
|
} catch (error) {
|
|
console.warn('History API URL', `解析失败: ${url}`)
|
|
return url
|
|
}
|
|
})()
|
|
const newUrl = getCleanUrl(resolvedUrl)
|
|
if (newUrl !== url) {
|
|
console.log('History API 拦截', resolvedUrl, newUrl)
|
|
return original.call(this, data, unused, newUrl, ...restArgs)
|
|
}
|
|
return original.call(this, data, unused, url, ...restArgs)
|
|
}
|
|
}
|
|
const originalPushState = unsafeWindow.history.pushState
|
|
unsafeWindow.history.pushState = createHistoryHook(originalPushState)
|
|
const originalReplaceState = unsafeWindow.history.replaceState
|
|
unsafeWindow.history.replaceState = createHistoryHook(originalReplaceState)
|
|
|
|
const clean = () => {
|
|
const newUrl = getCleanUrl(document.URL)
|
|
if (newUrl !== document.URL) {
|
|
console.log('直接清理', document.URL, newUrl)
|
|
window.history.replaceState(history.state, '', newUrl)
|
|
}
|
|
}
|
|
|
|
const { fullyLoaded } = await import('@/core/life-cycle')
|
|
const { urlChange } = await import('@/core/observer')
|
|
fullyLoaded(() => {
|
|
urlChange(() => clean())
|
|
})
|
|
}
|
|
export const component = defineComponentMetadata({
|
|
name: 'urlParamsClean',
|
|
displayName,
|
|
entry,
|
|
tags: [componentsTags.utils],
|
|
/* spell-checker: disable */
|
|
urlExclude: [/game\.bilibili\.com\/fgo/, /live\.bilibili\.com\/p\/html\/live-app-hotrank\//],
|
|
})
|