检测URL是否不可访问

This commit is contained in:
Allen 2025-04-30 17:28:03 +08:00
parent c70c4f1a5b
commit ec6393d719
4 changed files with 61 additions and 8 deletions

View File

@ -1,8 +1,4 @@
// Webview元素接口 import { WebviewTag } from "electron";
interface WebviewElement extends HTMLElement {
src: string;
addEventListener(event: string, listener: (event: any) => void): void;
}
// 菜单项接口 // 菜单项接口
interface MenuItem { interface MenuItem {
@ -78,9 +74,25 @@ function createMenuItem(item: MenuItem): HTMLLIElement {
li.appendChild(span); li.appendChild(span);
if (item.Url) { if (item.Url) {
li.addEventListener('click', () => { li.addEventListener('click', async () => {
(document.querySelector("webview") as WebviewElement).src = item.Url;
//(document.querySelector("webview") as WebviewElement).src = "https://www.baidu.com"; //(document.querySelector("webview") as WebviewElement).src = "https://www.baidu.com";
//(document.querySelector("webview") as WebviewTag).src = item.Url;
// 需要明确url是否指定http协议或https协议如果没有指定则默认使用http协议。因为没有指定协议会导致webview无法加载。
const url: string = item.Url.startsWith("http") ? item.Url : `http://${item.Url}`;
/**
* 访
* 1. DNS解析错误SSL证书错误等
* 2. 404500
*/
const result = await window.electronAPI.checkUrl(url);
if (result.ok && result.status >= 200 && result.status < 400) {
console.log('✅ URL 可访问:', result.status);
(document.querySelector("webview") as WebviewTag).src = url;
} else {
console.warn('❌ URL 不可访问:', result.error ?? `status ${result.status}`);
}
}); });
} }

View File

@ -1,6 +1,9 @@
import { app, BrowserWindow, globalShortcut, ipcMain, Menu, Tray } from 'electron'; import { app, BrowserWindow, globalShortcut, ipcMain, Menu, Tray } from 'electron';
import path from 'node:path'; import path from 'node:path';
import started from 'electron-squirrel-startup'; import started from 'electron-squirrel-startup';
import * as http from 'http';
import * as https from 'https';
import { URL } from 'url';
// Handle creating/removing shortcuts on Windows when installing/uninstalling. // Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (started) { if (started) {
@ -18,6 +21,42 @@ ipcMain.handle('set-cookie', async (event, cookie) => {
} }
}); });
ipcMain.handle('check-url', async (event, rawUrl: string) => {
try {
const url = new URL(rawUrl);
const lib = url.protocol === 'https:' ? https : http;
return await new Promise((resolve) => {
const req = lib.request(
{
method: 'HEAD',
hostname: url.hostname,
port: url.port || undefined,
path: url.pathname + url.search,
timeout: 3000,
},
(res) => {
resolve({ ok: true, status: res.statusCode })
req.destroy()
}
);
req.on('error', (err) => {
resolve({ ok: false, error: err.message })
});
req.on('timeout', () => {
req.destroy()
resolve({ ok: false, error: 'Timeout' })
});
req.end();
})
} catch (e) {
return { ok: false, error: 'Invalid URL' };
}
});
const createWindow = () => { const createWindow = () => {
// Create the browser window. // Create the browser window.
const win = new BrowserWindow({ const win = new BrowserWindow({

View File

@ -33,5 +33,6 @@ contextBridge.exposeInMainWorld('electronAPI', {
} }
} }
} }
} },
checkUrl: (url: string) => ipcRenderer.invoke('check-url', url)
}); });

View File

@ -1,5 +1,6 @@
export interface ElectronAPI { export interface ElectronAPI {
setCookie: (cookieString: string) => Promise<void>; setCookie: (cookieString: string) => Promise<void>;
checkUrl: (url: string) => Promise<{ ok: boolean; status: number; error?: string }>;
} }
declare global { declare global {