fix(modules/web): Bug fix; Support more widely legado remoteUrl

http://1.2.4.5:5000/<path>

http://www.example.com:5000/<path>
This commit is contained in:
Xwite
2024-10-09 21:44:24 +08:00
parent 8a1e165ffe
commit 19e37aec81
6 changed files with 110 additions and 79 deletions
+8 -8
View File
@@ -4,8 +4,8 @@
"private": true, "private": true,
"type": "module", "type": "module",
"engines": { "engines": {
"node": ">=16", "node": ">=20",
"pnpm": ">=8" "pnpm": ">=9"
}, },
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -16,13 +16,13 @@
"dependencies": { "dependencies": {
"@element-plus/icons-svg": "^2.3.1", "@element-plus/icons-svg": "^2.3.1",
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
"@vueuse/shared": "^10.11.1",
"@vueuse/core": "^11.1.0", "@vueuse/core": "^11.1.0",
"@vueuse/shared": "^11.1.0",
"axios": "^1.7.7", "axios": "^1.7.7",
"element-plus": "^2.8.4", "element-plus": "^2.8.4",
"hotkeys-js": "^3.13.7", "hotkeys-js": "^3.13.7",
"pinia": "^2.2.3", "pinia": "^2.2.4",
"vue": "^3.5.10", "vue": "^3.5.11",
"vue-router": "^4.4.5", "vue-router": "^4.4.5",
"vue3-virtual-scroll-list": "^0.2.1" "vue3-virtual-scroll-list": "^0.2.1"
}, },
@@ -34,9 +34,9 @@
"eslint-plugin-vue": "^9.28.0", "eslint-plugin-vue": "^9.28.0",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"sass": "^1.79.4", "sass": "^1.79.4",
"unplugin-auto-import": "^0.17.8", "unplugin-auto-import": "^0.18.3",
"unplugin-icons": "^0.18.5", "unplugin-icons": "^0.19.3",
"unplugin-vue-components": "^0.26.0", "unplugin-vue-components": "^0.27.4",
"vite": "^5.4.8" "vite": "^5.4.8"
} }
} }
+1 -1
View File
@@ -5,7 +5,7 @@ const SECOND = 1000;
const ajax = axios.create({ const ajax = axios.create({
baseURL: baseURL:
import.meta.env.VITE_API || import.meta.env.VITE_API ||
localStorage.getItem("remoteOrigin") || localStorage.getItem("remoteUrl") ||
location.origin, location.origin,
timeout: 120 * SECOND, timeout: 120 * SECOND,
}); });
+84 -39
View File
@@ -4,43 +4,85 @@ import { ElMessage } from "element-plus/es";
/** https://github.com/gedoor/legado/tree/master/app/src/main/java/io/legado/app/api */ /** https://github.com/gedoor/legado/tree/master/app/src/main/java/io/legado/app/api */
/** https://github.com/gedoor/legado/tree/master/app/src/main/java/io/legado/app/web */ /** https://github.com/gedoor/legado/tree/master/app/src/main/java/io/legado/app/web */
let legado_http_origin; /**@type string */
let legado_webSocket_origin; export let legado_http_entry_point;
/**@type string */
export let legado_webSocket_entry_point;
const setLeagdoHttpUrl = (http_url) => { /**
let legado_webSocket_port, url; * @param {string|URL} http_url
* @returns {URL}
* @throws {Error}
*/
export const validatorHttpUrl = (http_url) => {
try { try {
url = new URL(http_url); const url = new URL(http_url);
if (url.toString() === legado_http_entry_point)
throw new Error("Please input different url: " + legado_http_entry_point);
const { protocol } = url;
if (!protocol.startsWith("http"))
throw new Error("Expect http:/https: protocol but " + protocol);
return url;
} catch (e) { } catch (e) {
if (localStorage.getItem("remoteOrigin") == http_url) { if (localStorage.getItem("remoteUrl") == http_url) {
localStorage.removeItem("remoteOrigin"); localStorage.removeItem("remoteUrl");
console.warn("Remove remoteUrl from localStorage");
} }
throw new Error("Fail to parse Leagdo remoteOrigin: " + e); throw new Error("Fail to parse Leagdo remoteUrl " + http_url, { cause: e });
} }
const { protocol, hostname, port, origin } = url; };
if (!protocol.startsWith("http")) /**
throw new Error("unexpect protocol: " + http_url); * @param {string|URL} http_url
ajax.defaults.baseURL = origin; * @returns
//持久化 */
localStorage.setItem("remoteOrigin", origin); export const setLeagdoHttpUrl = (http_url) => {
legado_http_origin = origin; let url = new URL(location.origin); //默认当前网址的origin部分
try {
url = validatorHttpUrl(http_url);
} catch (e) {
console.warn(e);
console.info(
"setLeagdoHttpUrl: FallBack to location.origin: " + location.origin,
);
}
const { protocol, port, href } = url;
// websocket服务端口 为http服务端口 + 1
let legado_webSocket_port, legado_webSocket_protocol;
if (port !== "") { if (port !== "") {
legado_webSocket_port = Number(port) + 1; legado_webSocket_port = String(Number(port) + 1);
} else { } else {
legado_webSocket_port = protocol.startsWith("https:") ? "444" : "81"; legado_webSocket_port = protocol.startsWith("https:") ? "444" : "81";
} }
legado_webSocket_origin = `${protocol.startsWith("https:") ? "wss://" : "ws://"}${hostname}:${legado_webSocket_port}`; // websocket协议是否为加密版本
legado_webSocket_protocol = protocol.startsWith("https:")
? "wss://"
: "ws://";
console.info("legado_server_config:"); ajax.defaults.baseURL = href;
console.table({ legado_http_origin, legado_webSocket_origin }); //持久化
localStorage.setItem("remoteUrl", href);
legado_http_entry_point = href;
url.protocol = legado_webSocket_protocol;
url.port = legado_webSocket_port;
legado_webSocket_entry_point = url.href;
console.info("legado_api_config:");
console.table({
"http API入口": legado_http_entry_point,
"webSocket API入口": legado_webSocket_entry_point,
});
}; };
// 手动初始化 阅读web服务地址 // 手动初始化 阅读web服务地址
setLeagdoHttpUrl(ajax.defaults.baseURL); setLeagdoHttpUrl(ajax.defaults.baseURL);
/**
* @param {string|URL} http_url
* @returns
*/
const testLeagdoHttpUrlConnection = async (http_url) => { const testLeagdoHttpUrlConnection = async (http_url) => {
const { data = {} } = await ajax.get("/getReadConfig", { const { data = {} } = await ajax.get("/getReadConfig", {
baseURL: http_url, baseURL: new URL(http_url).toString(),
timeout: 3000, timeout: 3000,
}); });
// 返回结果应该是JSON 并有键值isSuccess // 返回结果应该是JSON 并有键值isSuccess
@@ -78,7 +120,7 @@ const saveBookProgressWithBeacon = (bookProgress) => {
if (!bookProgress) return; if (!bookProgress) return;
// 常规请求可能会被取消 使用Fetch keep-alive 或者 navigator.sendBeacon // 常规请求可能会被取消 使用Fetch keep-alive 或者 navigator.sendBeacon
navigator.sendBeacon( navigator.sendBeacon(
`${legado_http_origin}/saveBookProgress`, new URL("/saveBookProgress", legado_http_entry_point),
JSON.stringify(bookProgress), JSON.stringify(bookProgress),
); );
}; };
@@ -105,8 +147,9 @@ const search = (
/** @type {(data: string) => void} */ onReceive, /** @type {(data: string) => void} */ onReceive,
/** @type {() => void} */ onFinish, /** @type {() => void} */ onFinish,
) => { ) => {
const url = `${legado_webSocket_origin}/searchBook`; const socket = new WebSocket(
const socket = new WebSocket(url); new URL("/searchBook", legado_webSocket_entry_point),
);
socket.onopen = () => { socket.onopen = () => {
socket.send(`{"key":"${searchKey}"}`); socket.send(`{"key":"${searchKey}"}`);
@@ -150,9 +193,10 @@ const debug = (
/** @type {(data: string) => void} */ onReceive, /** @type {(data: string) => void} */ onReceive,
/** @type {() => void} */ onFinish, /** @type {() => void} */ onFinish,
) => { ) => {
const url = `${legado_webSocket_origin}/${ const url = new URL(
isBookSource ? "bookSource" : "rssSource" `/${isBookSource ? "bookSource" : "rssSource"}Debug`,
}Debug`; legado_webSocket_entry_point,
);
const socket = new WebSocket(url); const socket = new WebSocket(url);
@@ -175,8 +219,11 @@ const debug = (
* @param {string} coverUrl * @param {string} coverUrl
*/ */
const getProxyCoverUrl = (coverUrl) => { const getProxyCoverUrl = (coverUrl) => {
if (coverUrl.startsWith(legado_http_origin)) return coverUrl; if (coverUrl.startsWith(legado_http_entry_point)) return coverUrl;
return legado_http_origin + "/cover?path=" + encodeURIComponent(coverUrl); return new URL(
"/cover?path=" + encodeURIComponent(coverUrl),
legado_http_entry_point,
).href;
}; };
/** /**
* 从阅读获取需要特定处理的图片 * 从阅读获取需要特定处理的图片
@@ -184,15 +231,15 @@ const getProxyCoverUrl = (coverUrl) => {
* @param {number|`${number}`} width * @param {number|`${number}`} width
*/ */
const getProxyImageUrl = (src, width) => { const getProxyImageUrl = (src, width) => {
if (src.startsWith(legado_http_origin)) return src; if (src.startsWith(legado_http_entry_point)) return src;
return ( return new URL(
legado_http_origin +
"/image?path=" + "/image?path=" +
encodeURIComponent(src) + encodeURIComponent(src) +
"&url=" + "&url=" +
encodeURIComponent(sessionStorage.getItem("bookUrl")) + encodeURIComponent(sessionStorage.getItem("bookUrl")) +
"&width=" + "&width=" +
width width,
legado_http_entry_point,
); );
}; };
@@ -218,6 +265,4 @@ export default {
getProxyImageUrl, getProxyImageUrl,
testLeagdoHttpUrlConnection, testLeagdoHttpUrlConnection,
setLeagdoHttpUrl,
legado_http_origin,
}; };
+1
View File
@@ -3,6 +3,7 @@
// @ts-nocheck // @ts-nocheck
// noinspection JSUnusedGlobalSymbols // noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import // Generated by unplugin-auto-import
// biome-ignore lint: disable
export {} export {}
declare global { declare global {
const EffectScope: typeof import('vue')['EffectScope'] const EffectScope: typeof import('vue')['EffectScope']
+1 -1
View File
@@ -1,10 +1,10 @@
/* eslint-disable */ /* eslint-disable */
/* prettier-ignore */
// @ts-nocheck // @ts-nocheck
// Generated by unplugin-vue-components // Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399 // Read more: https://github.com/vuejs/core/pull/3399
export {} export {}
/* prettier-ignore */
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
BookItems: typeof import('./components/BookItems.vue')['default'] BookItems: typeof import('./components/BookItems.vue')['default']
+15 -30
View File
@@ -85,7 +85,11 @@ import { useBookStore } from "@/store";
import githubUrl from "@/assets/imgs/github.png"; import githubUrl from "@/assets/imgs/github.png";
import { useLoading } from "@/hooks/loading"; import { useLoading } from "@/hooks/loading";
import { Search as SearchIcon } from "@element-plus/icons-vue"; import { Search as SearchIcon } from "@element-plus/icons-vue";
import API from "@api"; import API, {
legado_http_entry_point,
validatorHttpUrl,
setLeagdoHttpUrl,
} from "@api";
export default defineComponent({ export default defineComponent({
beforeRouteEnter: (to, from, next) => { beforeRouteEnter: (to, from, next) => {
@@ -98,6 +102,8 @@ export default defineComponent({
// @ts-ignore // @ts-ignore
vm.saveReadConfig(data); vm.saveReadConfig(data);
}); });
} else {
next();
} }
}) })
.catch(() => next()); .catch(() => next());
@@ -182,33 +188,12 @@ export default defineComponent({
{ {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
inputPlaceholder: API.legado_http_origin, inputPlaceholder: legado_http_entry_point,
inputValidator: (url) => { inputValidator: (value) => {
try { try {
const { validatorHttpUrl(value);
origin,
protocol,
username,
password,
pathname,
search,
hash,
} = new URL(url);
console.log(new URL(url));
if (origin == API.legado_http_origin)
return "请输入非当前远程链接";
if (!protocol.startsWith("http")) return `不支持协议${protocol}`;
if (
pathname !== "/" ||
search !== "" ||
hash !== "" ||
password !== "" ||
username !== ""
)
return `目前仅支持输入${origin}`;
} catch (e) { } catch (e) {
console.warn(e); return e?.cause?.message ?? e.message;
return "URL解析失败,请重新输入";
} }
return true; return true;
}, },
@@ -218,17 +203,17 @@ export default defineComponent({
instance.confirmButtonLoading = true; instance.confirmButtonLoading = true;
instance.confirmButtonText = "校验中……"; instance.confirmButtonText = "校验中……";
// instance.inputValue // instance.inputValue
const url = instance.inputValue; const url = new URL(instance.inputValue);
API.testLeagdoHttpUrlConnection(url) API.testLeagdoHttpUrlConnection(url)
//API.getBookShelf() //API.getBookShelf()
.then(function (configStr) { .then(function (configStr) {
saveReadConfig(configStr); saveReadConfig(configStr);
instance.confirmButtonLoading = false; instance.confirmButtonLoading = false;
store.setConnectType("success"); store.setConnectType("success");
store.setConnectStatus("已连接 " + url);
store.clearSearchBooks(); store.clearSearchBooks();
store.setNewConnect(false); store.setNewConnect(false);
API.setLeagdoHttpUrl(url); setLeagdoHttpUrl(url);
store.setConnectStatus("已连接 " + url.toString());
fetchBookShelfData(); fetchBookShelfData();
done(); done();
}) })
@@ -341,7 +326,7 @@ export default defineComponent({
} else { } else {
ElMessage.error(response.data.errorMsg ?? "后端返回格式错误!"); ElMessage.error(response.data.errorMsg ?? "后端返回格式错误!");
} }
store.setConnectStatus("已连接 " + API.legado_http_origin); store.setConnectStatus("已连接 " + legado_http_entry_point);
store.setNewConnect(false); store.setNewConnect(false);
}); });
}; };