From 3907fef0a3e72d238cab23a06f5201342aeb173c Mon Sep 17 00:00:00 2001 From: root Date: Sat, 29 Aug 2026 13:49:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(ohos):=20=E7=A7=BB=E9=99=A4=E7=A1=AC?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E5=90=8E=E7=AB=AF=E5=87=AD=E6=8D=AE=EF=BC=8C?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E8=A7=84=E8=8C=83=E5=8C=96=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=20https?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Model.ets: defaultConnection 不再内置 url/apiKey,改为空白模板 - 新增 normalizeBaseUrl:补协议(默认 https)、去尾斜杠、去误粘的 /api/v1 裸域名走 http 会被反代 302 到门户站,客户端只拿到 404,表现为"连接直接失败" - ConnStore: 增删改与读取存量数据时统一规范化 url - 去掉 ensureDefaultConnection,首启不再预置连接,未配置时走统一提示 --- .../entry/src/main/ets/common/ConnStore.ets | 26 ++++++------- .../main/ets/entryability/EntryAbility.ets | 2 - .../entry/src/main/ets/model/Model.ets | 37 ++++++++++++++++++- .../entry/src/main/ets/pages/SettingsPage.ets | 2 +- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets index 8b0a299..49e62b4 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/common/ConnStore.ets @@ -1,7 +1,7 @@ import { preferences } from '@kit.ArkData'; import { Context } from '@kit.AbilityKit'; import { deviceInfo } from '@kit.BasicServicesKit'; -import { ConnectionConfig, AppSettings, emptySettings, defaultConnection } from '../model/Model'; +import { ConnectionConfig, AppSettings, emptySettings, defaultConnection, normalizeBaseUrl } from '../model/Model'; const PREF_NAME: string = 'homeagent_prefs'; const KEY_CONNECTIONS: string = 'connections_json'; @@ -31,6 +31,12 @@ export class ConnStore { } catch (e) { this.connections = []; } + // 存量数据可能是旧版本存进去的裸域名或带尾斜杠的地址,读出来时一并规范化, + // 否则老用户升级后仍然会拼出错误的请求地址。 + for (let i = 0; i < this.connections.length; i++) { + const c: ConnectionConfig = this.connections[i]; + c.url = normalizeBaseUrl(c.url); + } } const settingsJson: string = await this.prefs.get(KEY_SETTINGS, '') as string; if (settingsJson.length > 0) { @@ -42,18 +48,8 @@ export class ConnStore { } } - // 首次启动时预置默认连接(用户后端),避免所有页面空白 - async ensureDefaultConnection(): Promise { - await this.load(); - if (this.connections.length > 0) { - return; - } - const conn: ConnectionConfig = defaultConnection(); - conn.id = 'default'; - this.connections.push(conn); - this.settings.currentConnId = conn.id; - await this.save(); - } + // 不预置任何连接:地址与密钥属于用户私有配置,不能随源码分发。 + // 连接列表为空时各页面走"尚未配置后端连接"的统一提示,用户到设置页添加。 getConnections(): ConnectionConfig[] { return this.connections; @@ -82,7 +78,7 @@ export class ConnStore { const conn: ConnectionConfig = defaultConnection(); conn.id = Date.now().toString(36) + Math.floor(Math.random() * 10000).toString(36); conn.name = name; - conn.url = url; + conn.url = normalizeBaseUrl(url); conn.apiKey = apiKey; conn.type = 'webui'; this.connections.push(conn); @@ -99,7 +95,7 @@ export class ConnStore { const c: ConnectionConfig = this.connections[i]; if (c.id === id) { c.name = name; - c.url = url; + c.url = normalizeBaseUrl(url); c.apiKey = apiKey; break; } diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets index bcc6163..7962c91 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/entryability/EntryAbility.ets @@ -81,7 +81,6 @@ export default class EntryAbility extends UIAbility { windowStage.getMainWindow((err: BusinessError, win: window.Window) => { if (err.code !== 0) { connStore.init(this.context).then(async () => { - await connStore.ensureDefaultConnection(); const cur = connStore.getCurrentConnection(); if (cur !== null) { apiClient.setConnection(cur); @@ -100,7 +99,6 @@ export default class EntryAbility extends UIAbility { console.warn('[HomeAgent] setWindowLayoutFullScreen failed: ' + (e as Error).message); } connStore.init(this.context).then(async () => { - await connStore.ensureDefaultConnection(); const cur = connStore.getCurrentConnection(); if (cur !== null) { apiClient.setConnection(cur); diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets index b291562..d12dad6 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/model/Model.ets @@ -163,12 +163,45 @@ export function emptySettings(): AppSettings { return s; } +/** + * 规范化用户填写的后端地址。 + * + * 用户习惯直接敲域名(homeagent.example.xyz)或粘贴带路径的地址。 + * 三件事必须在存库前做掉,否则请求会以各种方式失败: + * + * 1) 补协议,且默认 https。 + * 很多反代把 http 整站 302 到别的主机(例如门户站 www.xxx), + * 重定向后的主机没有 API,客户端只会拿到 404 页面而不是 401/200, + * 表现为"连接直接失败"且看不出原因。默认 https 可以绕过整类问题。 + * 只有明确写了 http:// 的内网地址才走明文。 + * 2) 去掉结尾斜杠,避免拼出 //api/v1。 + * 3) 去掉用户误粘的 /api/v1 后缀,避免拼成 /api/v1/api/v1。 + */ +export function normalizeBaseUrl(raw: string): string { + let u: string = raw.trim(); + if (u.length === 0) { + return ''; + } + const lower: string = u.toLowerCase(); + if (!lower.startsWith('http://') && !lower.startsWith('https://')) { + u = 'https://' + u; + } + u = u.replace(/\/+$/, ''); + u = u.replace(/\/api\/v1$/, ''); + return u; +} + +/** + * 新建连接用的空白模板。 + * 这里不能写死任何地址或密钥:源码是公开的,硬编码等于把内网地址和访问凭据一起发布。 + * 地址与 API Key 由用户在「设置 - 连接」里填写,未配置时各页面统一提示(见 UserError.MSG_NO_CONN)。 + */ export function defaultConnection(): ConnectionConfig { const c: ConnectionConfig = { id: '', name: 'HomeAgent', - url: 'http://192.168.2.60:8080', - apiKey: 'jinrui233719', + url: '', + apiKey: '', type: 'webui', }; return c; diff --git a/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets b/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets index de3ad16..d2222dc 100644 --- a/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets +++ b/cmd/ohos/HomeAgent/entry/src/main/ets/pages/SettingsPage.ets @@ -854,7 +854,7 @@ export struct SettingsPage { .onChange((v: string) => { this.editName = v; }) - TextInput({ placeholder: '地址 (如 http://192.168.1.100:8080)', text: this.editUrl }) + TextInput({ placeholder: '地址 (域名或 http://192.168.1.100:8080)', text: this.editUrl }) .height(36).fontSize(13).fontColor(this.palette().textPrimary) .placeholderColor(this.palette().textMuted).backgroundColor(this.palette().bgInput) .borderRadius(RADIUS_SM).border({ width: 1, color: this.palette().border })