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:
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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,
|
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
+1
@@ -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']
|
||||||
|
|||||||
Vendored
+1
-1
@@ -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']
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user