diff --git a/src/EIAC_Desktop_Api.ts b/src/EIAC_Desktop_Api.ts
index c1ac81a..3179c8e 100644
--- a/src/EIAC_Desktop_Api.ts
+++ b/src/EIAC_Desktop_Api.ts
@@ -216,7 +216,7 @@ export interface TagResolutionConfig {
     /**
      * 缩放比例
      */
-    Percentage: number;
+    Percentage: string | number;
     /**
      * 特殊页面
      */
@@ -234,7 +234,7 @@ export interface SpecialPUrlItem {
     /**
      * 特殊页面缩放比例
      */
-    SPPer: number;
+    SPPer: string | number;
 }
 
 /**
diff --git a/src/main.ts b/src/main.ts
index 5f5bc13..4a45ec0 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -5,6 +5,8 @@ import * as http from 'http';
 import * as https from 'https';
 import { URL } from 'url';
 
+const isDevelopment = process.env.NODE_ENV === 'development';
+
 // Ensure only one instance is running
 const gotTheLock = app.requestSingleInstanceLock();
 if (!gotTheLock) {
@@ -32,34 +34,64 @@ ipcMain.handle('get-primary-display', () => screen.getPrimaryDisplay());
 // Check if the URL is available
 ipcMain.handle('check-url-available', async (event, rawUrl: string) => {
   try {
-    const url = new URL(rawUrl);
+    const url: URL = new URL(rawUrl);
     const lib = url.protocol === 'https:' ? https : http;
 
     return await new Promise((resolve) => {
-      const req = lib.request(
+      // 先用HEAD请求,如果遇到403,则再用GET请求再试一次(部分服务器可能禁止HEAD请求)。
+      const requestOptions: http.RequestOptions | https.RequestOptions = {
+        hostname: url.hostname,
+        port: url.port || undefined,
+        path: url.pathname + url.search,
+        headers: {
+          'Accept': '*/*',
+          'Accept-Encoding': 'gzip, deflate, br',
+          'Connection': 'keep-alive',
+          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
+        }
+      };
+      const headReq = lib.request(
         {
           method: 'HEAD',
-          hostname: url.hostname,
-          port: url.port || undefined,
-          path: url.pathname + url.search,
           timeout: 3000,
+          ...requestOptions
         },
         (res) => {
-          resolve({ ok: true, status: res.statusCode })
-          req.destroy()
+          console.log('check-url-available HEAD', url.toString(), res.statusCode, res.statusMessage);
+          if (res.statusCode === 403) {
+            headReq.destroy()
+            const getReq = lib.get({
+              method: 'GET',
+              ...requestOptions
+            }, (res) => {
+              console.log('check-url-available GET', url.toString(), res.statusCode, res.statusMessage);
+              resolve({ ok: true, status: res.statusCode, message: res.statusMessage });
+              getReq.destroy()
+            });
+            getReq.on('error', (err) => {
+              resolve({ ok: false, error: err.message });
+            });
+            getReq.on('timeout', () => {
+              resolve({ ok: false, error: 'Timeout' });
+              getReq.destroy();
+            });
+          } else {
+            resolve({ ok: true, status: res.statusCode, message: res.statusMessage });
+            headReq.destroy();
+          }
         }
       );
 
-      req.on('error', (err) => {
-        resolve({ ok: false, error: err.message })
+      headReq.on('error', (err) => {
+        resolve({ ok: false, error: err.message });
       });
 
-      req.on('timeout', () => {
-        req.destroy()
-        resolve({ ok: false, error: 'Timeout' })
+      headReq.on('timeout', () => {
+        resolve({ ok: false, error: 'Timeout' });
+        headReq.destroy();
       });
 
-      req.end();
+      headReq.end();
     })
   } catch (e) {
     return { ok: false, error: 'Invalid URL' };
@@ -141,7 +173,9 @@ const createWindow = () => {
 
   win.webContents.on('did-attach-webview', (event, webContents) => {
     webContents.setWindowOpenHandler((details) => {
-      console.log('webview-new-window', webContents, details);
+      if (isDevelopment) {
+        console.log('webview-new-window', webContents, details);
+      }
       win.webContents.send('webview-new-window', webContents.id, details.url);
       return { action: 'deny' };
     });
@@ -172,6 +206,9 @@ const createWindow = () => {
     }
   };
   globalShortcut.register("CommandOrControl+Shift+I", handleDevTools);
+  if (isDevelopment) {
+    win.webContents.openDevTools();
+  }
 
   // and load the login.html of the app.
   if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
@@ -185,7 +222,7 @@ const createWindow = () => {
     { label: '显示窗口', click: () => win.show() },
     { label: '退出程序', click: () => app.exit() }
   ]);
-  const iconPath = process.env.NODE_ENV === 'development' ? path.join(__dirname, '../../assets/tray.png') : path.join(process.resourcesPath, 'assets', 'tray.png');
+  const iconPath = isDevelopment ? path.join(__dirname, '../../assets/tray.png') : path.join(process.resourcesPath, 'assets', 'tray.png');
   const tray = new Tray(iconPath);
   tray.setToolTip('中国电信-工作台');
   tray.setContextMenu(contextMenu);
diff --git a/src/preload.ts b/src/preload.ts
index e41c1c6..34b8b5a 100644
--- a/src/preload.ts
+++ b/src/preload.ts
@@ -4,36 +4,63 @@
 import { contextBridge, ipcRenderer } from 'electron';
 
 contextBridge.exposeInMainWorld('electronAPI', {
-  // 打开新标签页
+  /**
+   * 在新标签页打开URL
+   * @param callback 回调函数,参数为webContentId和url。其中webContentId是请求打开URL的webview的id。
+   */
   onOpenTab: (callback: (webContentId: number, url: string) => void) => {
     ipcRenderer.on('webview-new-window', (_event, webContentId, url) => callback(webContentId, url));
   },
 
-  // 获取当前屏幕的缩放比例和分辨率
-  getPrimaryDisplay: () => ipcRenderer.invoke('get-primary-display'),
+  /**
+   * 获取当前屏幕的缩放比例和分辨率
+   * @returns 缩放比例和分辨率
+   */
+  getPrimaryDisplay: () => ipcRenderer.invoke('get-primary-display') as Promise<Electron.Display>,
 
-  // 检查URL是否可用
+  /**
+   * 检查URL是否可用
+   * @param url 要检查的URL
+   * @returns 是否可用
+   */
   checkUrlAvailable: (url: string) => ipcRenderer.invoke('check-url-available', url),
 
-  // 设置webview的cookie
+  /**
+   * 设置webview的cookie
+   * @param url 要设置cookie的URL
+   * @param cookie cookie字符串
+   */
   setWebviewCookie: (url: string, cookie: string) => ipcRenderer.invoke('set-webview-cookie', url, cookie),
 
-  // 设置 sessionStorage
+  /**
+   * 按键将值设置到sessionStorage
+   * @param key 键
+   * @param value 值
+   */
   setSessionStorage: (key: string, value: string) => {
     window.sessionStorage.setItem(key, value);
   },
 
-  // 获取 sessionStorage
+  /**
+   * 从sessionStorage中获取指定键的值
+   * @param key 键
+   * @returns 值
+   */
   getSessionStorage: (key: string) => {
     return window.sessionStorage.getItem(key);
   },
 
-  // 删除 sessionStorage
+  /**
+   * 从sessionStorage中删除指定键的值
+   * @param key 键
+   */
   removeSessionStorage: (key: string) => {
     window.sessionStorage.removeItem(key);
   },
 
-  // 清空 sessionStorage
+  /**
+   * 清空sessionStorage
+   */
   clearSessionStorage: () => {
     window.sessionStorage.clear();
   }
diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts
index 3295f1a..e9947ce 100644
--- a/src/types/electron.d.ts
+++ b/src/types/electron.d.ts
@@ -1,11 +1,46 @@
 export interface ElectronAPI {
+  /**
+   * 在新标签页打开URL
+   * @param callback 回调函数,参数为webContentId和url。其中webContentId是请求打开URL的webview的id。
+   */
   onOpenTab: (callback: (webContentId: number, url: string) => void) => void;
+  /**
+   * 获取当前屏幕的缩放比例和分辨率
+   * @returns 缩放比例和分辨率
+   */
   getPrimaryDisplay: () => Promise<Electron.Display>;
+  /**
+   * 检查URL是否可用
+   * @param url 要检查的URL
+   * @returns 是否可用
+   */
   checkUrlAvailable: (url: string) => Promise<{ ok: boolean; status: number; error?: string }>;
+  /**
+   * 设置webview的cookie
+   * @param url 要设置cookie的URL
+   * @param cookie cookie字符串
+   */
   setWebviewCookie: (url: string, cookie: string) => Promise<boolean>;
+  /**
+   * 按键将值设置到sessionStorage
+   * @param key 键
+   * @param value 值
+   */
   setSessionStorage: (key: string, value: string) => void;
+  /**
+   * 从sessionStorage中获取指定键的值
+   * @param key 键
+   * @returns 值
+   */
   getSessionStorage: (key: string) => string | null;
+  /**
+   * 从sessionStorage中删除指定键的值
+   * @param key 键
+   */
   removeSessionStorage: (key: string) => void;
+  /**
+   * 清空sessionStorage
+   */
   clearSessionStorage: () => void;
 }