一、簡介
User-Agent(簡稱UA)是一個特殊的字符串,包含設備類型、操作系統及版本等關鍵信息。在Web開發中,這個字符串使服務器能夠識別請求的來源設備及其特性,從而根據這些信息提供定製化的內容和服務。如果頁面無法正確識別UA,可能會導致多種異常情況。例如,為移動設備優化的頁面佈局可能會在桌面設備上顯示錯亂,反之亦然。此外,某些特定的瀏覽器功能或CSS樣式可能僅在特定的瀏覽器版本中受支持,如果頁面無法根據UA字符串做出正確的判斷,就可能導致渲染問題或邏輯錯誤。
二、默認User-Agent結構
2.1 默認User-Agent定義
Mozilla/5.0 ({DeviceType}; {OSName} {OSVersion}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{ChromeCompatibleVersion}.0.0.0 Safari/537.36 ArkWeb/{ArkWeb VersionCode} {DeviceCompat} {擴展區}
舉例説明
Mozilla/5.0 (Phone; OpenHarmony 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile
字段説明
|
字段
|
含義
|
|
DeviceType
|
當前的設備類型。取值範圍:
- Phone:手機設備
- Tablet:平板設備
- PC:2in1設備
|
|
OSName
|
基礎操作系統名稱。
默認取值:OpenHarmony
|
|
OSVersion
|
基礎操作系統版本,兩位數字,M.S。
通過系統參數const.ohos.fullname解析版本號得到,取版本號部分M.S前兩位。
默認取值:例如5.0
|
|
ChromeCompatibleVersion
|
兼容Chrome主版本的版本號,從114版本開始演進。
默認取值:114
|
|
ArkWeb
|
HarmonyOS版本Web內核名稱。
默認取值:ArkWeb
ArkWeb VersionCode
ArkWeb版本號,格式a.b.c.d。
默認取值:例如4.1.6.1
|
|
DeviceCompat
|
前向兼容字段。
默認取值:Mobile
|
|
擴展區
|
三方應用可以擴展的字段。
三方應用使用ArkWeb組件時,可以做UA擴展,例如加入APP相關信息標識。
|
説明
- 當前默認User-Agent的ArkWeb字段前有兩個空格。
- 當前通過User-Agent中是否含有"Mobile"字段來判斷是否開啓前端HTML頁面中meta標籤的viewport屬性。當User-Agent中不含有"Mobile"字段時,meta標籤中viewport屬性默認關閉,此時可通過顯性設置metaViewport屬性為true來覆蓋關閉狀態。
- 建議通過OpenHarmony關鍵字識別是否是HarmonyOS設備,同時可以通過DeviceType識別設備類型用於不同設備上的頁面顯示(ArkWeb關鍵字表示設備使用的web內核,OpenHarmony關鍵字表示設備使用的操作系統,因此推薦通過OpenHarmony關鍵字識別是否是HarmonyOS設備)。
- {DistributionOSName}和{DistributionOSVersion}字段在API version 15之前的版本中未啓用,從API version 15版本開始不在默認User-Agent中體現。
三、自定義User-Agent結構
在下面的示例中,通過調用getUserAgent()接口獲取當前默認的用户代理(User-Agent)字符串。這一接口提供的默認User-Agent信息為開發者提供了基礎,使開發者能夠基於這個默認信息進行定製或擴展。
示例效果圖
示例代碼
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct TestUserAgent {
@State message: string = 'getUserAgent';
controller: webview.WebviewController = new webview.WebviewController()
build() {
Column({space: 20}) {
Button(this.message)
.id('TestUserAgentHelloWorld')
.fontSize($r('app.float.page_text_font_20fp'))
.fontWeight(FontWeight.Bold)
.onClick(() => {
try {
let userAgent = this.controller.getUserAgent();
console.log("獲取 userAgent: " + userAgent);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'www.baidu.com', controller: this.controller })
}
.height('100%')
.width('100%')
}
}
以下示例通過 setCustomUserAgent() 接口設置自定義用户代理,但請注意,此操作會覆蓋系統的用户代理。因此,我們建議將擴展字段追加在默認用户代理的末尾,比如三方應用程序的開發場景,可以在系統默認用户代理字符串的末尾追加特定的APP標識,這樣既能保留原有用户代理信息,又能增加自定義的應用識別信息。
當Web組件src設置了url時,建議在onControllerAttached回調事件中設置User-Agent,設置方式請參考示例。不建議將User-Agent設置在onLoadIntercept回調事件中,會概率性出現設置失敗。如果未在onControllerAttached回調事件中設置User-Agent。再調用setCustomUserAgent方法時,可能會出現加載的頁面與實際設置User-Agent不符的異常現象。
當Web組件src設置為空字符串時,建議先調用setCustomUserAgent方法設置User-Agent,再通過loadUrl加載具體頁面。示例效果圖
示例代碼
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = "TestUserAgent"
@Entry
@Component
struct TestUserAgent {
@State message: string = 'getUserAgent';
controller: webview.WebviewController = new webview.WebviewController()
// 三方應用相關信息標識
@State customUserAgent: string = ' DemoApp 自定義用户代理';
build() {
Column({space: 20}) {
Button(this.message)
.id('TestUserAgentHelloWorld')
.fontSize($r('app.float.page_text_font_20fp'))
.fontWeight(FontWeight.Bold)
.onClick(() => {
try {
let userAgent = this.controller.getUserAgent();
let customUserAgent = this.controller.getCustomUserAgent()
console.log("獲取 userAgent: " + userAgent);
console.log("獲取 customUserAgent: " + customUserAgent);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'https://www.baidu.com/', controller: this.controller })
.domStorageAccess(true)
.onControllerAttached(() =>{
console.log("執行了 onControllerAttached 回調");
try {
let userAgent = this.controller.getUserAgent()+ this.customUserAgent
this.controller.setCustomUserAgent(userAgent)
}catch (error){
console.error(TAG, `ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
}
.height('100%')
.width('100%')
}
}
從API version 20開始,可通過 setAppCustomUserAgent() 接口設置應用級自定義用户代理,或者通過 setUserAgentForHosts() 對特定網站設置應用級自定義用户代理,覆蓋系統的用户代理,應用內所有Web組件生效。
建議在Web組件創建前先調用靜態接口getDefaultUserAgent獲取默認的用户代理(User-Agent)字符串,然後調用setAppCustomUserAgent,setUserAgentForHosts方法設置User-Agent,再創建指定src的Web組件或通過loadUrl加載具體頁面。
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct TestUserAgent2 {
controller: webview.WebviewController = new webview.WebviewController();
@State userAgent: string = '';
aboutToAppear(): void {
try {
webview.WebviewController.initializeWebEngine();
let defaultUserAgent = webview.WebviewController.getDefaultUserAgent();
let appUA = defaultUserAgent + " appUA ";
webview.WebviewController.setAppCustomUserAgent(appUA+" application");
webview.WebviewController.setUserAgentForHosts(
appUA + "specific_net",
[
"developer.huawei.com",
"www.deepseek.com",
"www.baidu.com"
]
);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
}
build() {
Column({space: 20}) {
Button('getCustomUserAgent')
.onClick(() => {
try {
this.userAgent = this.controller.getCustomUserAgent();
console.log("通過getCustomUserAgent()接口獲取自定義用户代理 userAgent: " + this.userAgent);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'https://www.baidu.com', controller: this.controller })
}
}
}
在下面的示例中,通過getCustomUserAgent()接口獲取自定義用户代理。
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct TestUserAgent2 {
controller: webview.WebviewController = new webview.WebviewController();
@State userAgent: string = '';
aboutToAppear(): void {
try {
webview.WebviewController.initializeWebEngine();
let defaultUserAgent = webview.WebviewController.getDefaultUserAgent();
let appUA = defaultUserAgent + " appUA ";
webview.WebviewController.setAppCustomUserAgent(appUA+" application");
webview.WebviewController.setUserAgentForHosts(
appUA + "spefical_net",
[
"developer.huawei.com",
"www.deepseek.com",
"www.baidu.com"
]
);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
}
build() {
Column({space: 20}) {
Button('getCustomUserAgent')
.onClick(() => {
try {
this.userAgent = this.controller.getCustomUserAgent();
console.log("通過getCustomUserAgent()接口獲取自定義用户代理 userAgent: " + this.userAgent);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'https://www.baidu.com', controller: this.controller })
}
}
}
四、相關User-Agent接口優先級
|
接口名稱
|
優先級
|
説明
|
|
setCustomUserAgent
|
最高
|
對調用的Web組件生效。
|
|
setUserAgentForHosts
|
低於setCustomUserAgent
|
對應用中所有Web組件訪問指定網站生效。
|
|
setAppCustomUserAgent
|
低於setUserAgentForHosts
|
對應用中所有Web組件生效。
|
|
ArkWeb默認UA
|
最低
|
對應用中所有Web組件生效,只讀,通過getDefaultUserAgent獲取。
|
五、常見問題
5.1 如何通過User-Agent來識別HarmonyOS操作系統中不同設備
HarmonyOS設備的識別主要通過User-Agent中的系統、系統版本和設備類型三個維度來判斷。建議同時檢查系統、系統版本和設備類型,以確保更準確的設備識別。
5.1.1 系統識別
通過User-Agent中的{OSName}字段識別HarmonyOS系統。
const isHarmonyOS = () => /OpenHarmony/i.test(navigator.userAgent);
5.1.2 系統版本識別
通過User-Agent中的{OSName}和{OSVersion}字段識別HarmonyOS系統及系統版本。格式為:OpenHarmony + 版本號。
// 檢測是否是HarmonyOS系統
const matches = navigator.userAgent.match(/OpenHarmony (\d+\.?\d*)/);
matches?.length && Number(matches[1]) > 0
// 檢測是否是HarmonyOS NEXT系統
const matches = navigator.userAgent.match(/OpenHarmony (\d+\.?\d*)/);
matches?.length && Number(matches[1]) >= 5;
5.1.3 設備類型識別
通過deviceType字段來識別不同設備類型。
// 檢測是否為手機設備
const isPhone = () => /Phone/i.test(navigator.userAgent);
// 檢測是否為平板設備
const isTablet = () => /Tablet/i.test(navigator.userAgent);
// 檢測是否為2in1設備
const is2in1 = () => /PC/i.test(navigator.userAgent);
5.2 如何模擬HarmonyOS操作系統的User-Agent進行前端調試
在Windows/Mac/Linux等操作系統中,可以通過Chrome/Edge/Firefox等瀏覽器DevTools提供的User-Agent複寫能力,模擬HarmonyOS User-Agent。
5.3 如何在HarmonyOS中自定義User-Agent以實現H5兼容性
HarmonyOS提供setCustomUserAgent接口以支持User-Agent的自定義設置。為適配移動端H5頁面通常依賴的UA標識檢測(如Mobile、Android等),並確保不覆蓋系統默認UA信息,推薦按如下方式操作:首先通過setCustomUserAgent()接口獲取系統默認User-Agent字符串,隨後將H5兼容所需的自定義標識字段追加至該字符串末尾,最後調用setCustomUserAgent接口設置修改後的完整UA字符串。