fix: 兼容调试模式
This commit is contained in:
parent
2307639779
commit
b2c365ecbf
4
App.vue
4
App.vue
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
getCurrentWebviewToken,
|
|
||||||
getCurrentWebviewUrl,
|
getCurrentWebviewUrl,
|
||||||
|
refreshCurrentWebviewToken,
|
||||||
} from "./utils/webview-token";
|
} from "./utils/webview-token";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -19,7 +19,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
logCurrentWebviewToken(scene) {
|
logCurrentWebviewToken(scene) {
|
||||||
const currentUrl = getCurrentWebviewUrl();
|
const currentUrl = getCurrentWebviewUrl();
|
||||||
const token = getCurrentWebviewToken();
|
const token = refreshCurrentWebviewToken(currentUrl);
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
console.log("[webview-token][" + scene + "]", token);
|
console.log("[webview-token][" + scene + "]", token);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { refreshCurrentWebviewToken } from "../utils/webview-token";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
|
|
@ -47,6 +49,9 @@ export default {
|
||||||
default: "120rpx",
|
default: "120rpx",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
refreshCurrentWebviewToken();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleBack() {
|
handleBack() {
|
||||||
if (getCurrentPages().length > 1) {
|
if (getCurrentPages().length > 1) {
|
||||||
|
|
|
||||||
48
index.html
48
index.html
|
|
@ -9,6 +9,54 @@
|
||||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var locationObject = window.location || {};
|
||||||
|
var currentHref = String(locationObject.href || "");
|
||||||
|
var currentHash = String(locationObject.hash || "");
|
||||||
|
var currentSearch = String(locationObject.search || "");
|
||||||
|
var malformedPathPattern =
|
||||||
|
/(?:%3C%=%20BASE_URL%20%%3E|%3C%=%20VUE_APP_INDEX_CSS_HASH%20%%3E|<%=\s*BASE_URL\s*%>|<%=\s*VUE_APP_INDEX_CSS_HASH\s*%>|VUE_APP_INDEX_CSS_HASH|%%3Estatic\/index)/i;
|
||||||
|
|
||||||
|
if (!malformedPathPattern.test(currentHref)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalizedQuery = currentSearch;
|
||||||
|
if (!normalizedQuery) {
|
||||||
|
var tokenMatcher = currentHref.match(
|
||||||
|
/(?:[?&#]|^)(token|access_token)=([^&#]+)/i
|
||||||
|
);
|
||||||
|
if (tokenMatcher && tokenMatcher[2]) {
|
||||||
|
normalizedQuery = "?token=" + tokenMatcher[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalizedRoutePath = "/";
|
||||||
|
if (currentHash.indexOf("#/") === 0) {
|
||||||
|
var hashRoute = currentHash.slice(1);
|
||||||
|
var hashQueryIndex = hashRoute.indexOf("?");
|
||||||
|
if (hashQueryIndex > -1) {
|
||||||
|
if (!normalizedQuery) {
|
||||||
|
normalizedQuery = hashRoute.slice(hashQueryIndex);
|
||||||
|
}
|
||||||
|
hashRoute = hashRoute.slice(0, hashQueryIndex);
|
||||||
|
}
|
||||||
|
normalizedRoutePath = hashRoute || "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedRoutePath.charAt(0) !== "/") {
|
||||||
|
normalizedRoutePath = "/" + normalizedRoutePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetUrl = "/bmt" + normalizedRoutePath;
|
||||||
|
if (normalizedQuery) {
|
||||||
|
targetUrl += normalizedQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.replace(targetUrl);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<title></title>
|
<title></title>
|
||||||
<!--preload-links-->
|
<!--preload-links-->
|
||||||
<!--app-context-->
|
<!--app-context-->
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"h5" : {
|
"h5" : {
|
||||||
"router" : {
|
"router" : {
|
||||||
"base" : "/bmt/",
|
"base" : "/bmt/",
|
||||||
"mode" : "history"
|
"mode" : "hash"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
<!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>白马交易所</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
|
<!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>白马交易所</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
|
||||||
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=/bmt/static/index.883130ca.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=/bmt/static/js/chunk-vendors.98a0fd8f.js></script><script src=/bmt/static/js/index.eb295c71.js></script></body></html>
|
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=/bmt/static/index.883130ca.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=/bmt/static/js/chunk-vendors.98a0fd8f.js></script><script src=/bmt/static/js/index.fa34fa02.js></script></body></html>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
unpackage/dist/build/web/static/js/pages-assets-points-convert-list.ced2d19e.js
vendored
Normal file
1
unpackage/dist/build/web/static/js/pages-assets-points-convert-list.ced2d19e.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -61,6 +61,7 @@ export default function request(options) {
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
const bearerToken = "Bearer " + token;
|
const bearerToken = "Bearer " + token;
|
||||||
|
requestHeader["Authori-zation"] = bearerToken;
|
||||||
requestHeader.Authorization = bearerToken;
|
requestHeader.Authorization = bearerToken;
|
||||||
}
|
}
|
||||||
const shouldHandleLoading = showGlobalLoading(options);
|
const shouldHandleLoading = showGlobalLoading(options);
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,229 @@
|
||||||
function findTokenInText(text) {
|
const WEBVIEW_TOKEN_STORAGE_KEY = "bmt_webview_token";
|
||||||
|
let cachedToken = "";
|
||||||
|
const MAX_NESTED_PARSE_DEPTH = 4;
|
||||||
|
const NESTED_URL_PARAM_KEYS = [
|
||||||
|
"url",
|
||||||
|
"targetUrl",
|
||||||
|
"target_url",
|
||||||
|
"redirect",
|
||||||
|
"redirectUrl",
|
||||||
|
"redirect_url",
|
||||||
|
"redirectUri",
|
||||||
|
"redirect_uri",
|
||||||
|
"returnUrl",
|
||||||
|
"return_url",
|
||||||
|
"link",
|
||||||
|
"href",
|
||||||
|
];
|
||||||
|
const NESTED_URL_PARAM_KEYS_LOWER = NESTED_URL_PARAM_KEYS.map((item) =>
|
||||||
|
item.toLowerCase(),
|
||||||
|
);
|
||||||
|
|
||||||
|
function safeDecodeURIComponent(value) {
|
||||||
|
if (!value) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(value);
|
||||||
|
} catch (error) {
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeMultiEncodedValue(value) {
|
||||||
|
let currentValue = String(value || "");
|
||||||
|
if (!currentValue) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let round = 0; round < 4; round += 1) {
|
||||||
|
const decodedValue = safeDecodeURIComponent(currentValue);
|
||||||
|
if (!decodedValue || decodedValue === currentValue) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentValue = decodedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeTokenValue(token) {
|
||||||
|
let normalizedToken = decodeMultiEncodedValue(token || "").trim();
|
||||||
|
if (!normalizedToken) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^bearer\s+/i.test(normalizedToken)) {
|
||||||
|
normalizedToken = normalizedToken.replace(/^bearer\s+/i, "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashIndex = normalizedToken.indexOf("#");
|
||||||
|
if (hashIndex > -1) {
|
||||||
|
normalizedToken = normalizedToken.slice(0, hashIndex).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ampersandIndex = normalizedToken.indexOf("&");
|
||||||
|
if (ampersandIndex > -1) {
|
||||||
|
normalizedToken = normalizedToken.slice(0, ampersandIndex).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseQueryByRegex(queryText) {
|
||||||
|
const query = String(queryText || "").trim();
|
||||||
|
if (!query) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedQuery = query.replace(/^[?#&/]+/, "");
|
||||||
|
if (!normalizedQuery) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const entries = [];
|
||||||
|
const pairs = normalizedQuery.split("&");
|
||||||
|
for (let index = 0; index < pairs.length; index += 1) {
|
||||||
|
const pair = String(pairs[index] || "");
|
||||||
|
if (!pair) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const splitIndex = pair.indexOf("=");
|
||||||
|
if (splitIndex === -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = pair.slice(0, splitIndex);
|
||||||
|
const value = pair.slice(splitIndex + 1);
|
||||||
|
if (!key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.push({
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findTokenInText(text, depth = 0) {
|
||||||
|
if (depth > MAX_NESTED_PARSE_DEPTH) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
if (!text) {
|
if (!text) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryIndex = text.indexOf("?");
|
const rawText = String(text || "").trim();
|
||||||
if (queryIndex === -1) {
|
if (!rawText) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawQueryText = text.slice(queryIndex + 1);
|
const candidates = [];
|
||||||
const hashIndex = rawQueryText.indexOf("#");
|
const queryIndex = rawText.indexOf("?");
|
||||||
const queryText =
|
const hashIndex = rawText.indexOf("#");
|
||||||
hashIndex === -1 ? rawQueryText : rawQueryText.slice(0, hashIndex);
|
|
||||||
|
if (queryIndex > -1) {
|
||||||
|
let queryCandidate = rawText.slice(queryIndex + 1);
|
||||||
|
const hashInQuery = queryCandidate.indexOf("#");
|
||||||
|
if (hashInQuery > -1) {
|
||||||
|
queryCandidate = queryCandidate.slice(0, hashInQuery);
|
||||||
|
}
|
||||||
|
candidates.push(queryCandidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashIndex > -1) {
|
||||||
|
candidates.push(rawText.slice(hashIndex + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
candidates.push(rawText);
|
||||||
|
|
||||||
|
for (let index = 0; index < candidates.length; index += 1) {
|
||||||
|
let queryText = String(candidates[index] || "").trim();
|
||||||
|
if (!queryText) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextQueryIndex = queryText.indexOf("?");
|
||||||
|
if (nextQueryIndex > -1) {
|
||||||
|
queryText = queryText.slice(nextQueryIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
queryText = queryText.replace(/^[/#&]+/, "");
|
||||||
|
if (!queryText || queryText.indexOf("=") === -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const search = new URLSearchParams(queryText);
|
const search = new URLSearchParams(queryText);
|
||||||
return search.get("token") || "";
|
const token = search.get("token") || search.get("access_token") || "";
|
||||||
|
if (token) {
|
||||||
|
return sanitizeTokenValue(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let keyIndex = 0; keyIndex < NESTED_URL_PARAM_KEYS.length; keyIndex += 1) {
|
||||||
|
const nestedKey = NESTED_URL_PARAM_KEYS[keyIndex];
|
||||||
|
const nestedValue = search.get(nestedKey) || "";
|
||||||
|
if (!nestedValue) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedDecodedValue = decodeMultiEncodedValue(nestedValue);
|
||||||
|
const nestedToken =
|
||||||
|
findTokenInText(nestedValue, depth + 1) ||
|
||||||
|
findTokenInText(nestedDecodedValue, depth + 1);
|
||||||
|
if (nestedToken) {
|
||||||
|
return nestedToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Continue to fallback regex mode.
|
||||||
|
}
|
||||||
|
|
||||||
|
const matcher = queryText.match(
|
||||||
|
/(?:^|[?&#/])(token|access_token)=([^&#]+)/i,
|
||||||
|
);
|
||||||
|
if (matcher && matcher[2]) {
|
||||||
|
return sanitizeTokenValue(matcher[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fallbackEntries = parseQueryByRegex(queryText);
|
||||||
|
for (let entryIndex = 0; entryIndex < fallbackEntries.length; entryIndex += 1) {
|
||||||
|
const entry = fallbackEntries[entryIndex];
|
||||||
|
const entryKey = String(entry.key || "");
|
||||||
|
const entryValue = String(entry.value || "");
|
||||||
|
if (!entryKey || !entryValue) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedEntryKey = entryKey.toLowerCase();
|
||||||
|
const isTokenKey =
|
||||||
|
normalizedEntryKey === "token" || normalizedEntryKey === "access_token";
|
||||||
|
if (isTokenKey) {
|
||||||
|
return sanitizeTokenValue(entryValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isNestedUrlKey =
|
||||||
|
NESTED_URL_PARAM_KEYS_LOWER.indexOf(normalizedEntryKey) > -1;
|
||||||
|
if (!isNestedUrlKey) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedDecodedValue = decodeMultiEncodedValue(entryValue);
|
||||||
|
const nestedToken =
|
||||||
|
findTokenInText(entryValue, depth + 1) ||
|
||||||
|
findTokenInText(nestedDecodedValue, depth + 1);
|
||||||
|
if (nestedToken) {
|
||||||
|
return nestedToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractTokenFromUrl(url) {
|
export function extractTokenFromUrl(url) {
|
||||||
|
|
@ -57,6 +267,91 @@ export function getCurrentWebviewUrl() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCurrentWebviewToken() {
|
function getH5ReferrerUrl() {
|
||||||
return extractTokenFromUrl(getCurrentWebviewUrl());
|
// #ifdef H5
|
||||||
|
if (typeof document !== "undefined") {
|
||||||
|
return String(document.referrer || "").trim();
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeToken(token) {
|
||||||
|
return sanitizeTokenValue(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTokenToStorage(token) {
|
||||||
|
const normalizedToken = normalizeToken(token);
|
||||||
|
if (!normalizedToken) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedToken = normalizedToken;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof uni !== "undefined" && uni.setStorageSync) {
|
||||||
|
uni.setStorageSync(WEBVIEW_TOKEN_STORAGE_KEY, normalizedToken);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore storage failures and keep in-memory fallback.
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readTokenFromStorage() {
|
||||||
|
if (cachedToken) {
|
||||||
|
return cachedToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof uni !== "undefined" && uni.getStorageSync) {
|
||||||
|
const token = normalizeToken(uni.getStorageSync(WEBVIEW_TOKEN_STORAGE_KEY));
|
||||||
|
if (token) {
|
||||||
|
cachedToken = token;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore storage failures and fallback to runtime token extraction.
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCurrentWebviewToken(token) {
|
||||||
|
return saveTokenToStorage(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function refreshCurrentWebviewToken(url) {
|
||||||
|
const candidateUrls = [];
|
||||||
|
const inputUrl = String(url || "").trim();
|
||||||
|
const currentUrl = String(getCurrentWebviewUrl() || "").trim();
|
||||||
|
const referrerUrl = getH5ReferrerUrl();
|
||||||
|
|
||||||
|
if (inputUrl) {
|
||||||
|
candidateUrls.push(inputUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUrl && candidateUrls.indexOf(currentUrl) === -1) {
|
||||||
|
candidateUrls.push(currentUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (referrerUrl && candidateUrls.indexOf(referrerUrl) === -1) {
|
||||||
|
candidateUrls.push(referrerUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let index = 0; index < candidateUrls.length; index += 1) {
|
||||||
|
const nextToken = extractTokenFromUrl(candidateUrls[index]);
|
||||||
|
if (nextToken) {
|
||||||
|
return saveTokenToStorage(nextToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return readTokenFromStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCurrentWebviewToken() {
|
||||||
|
return refreshCurrentWebviewToken();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue