HarmonyOS 鸿蒙Next中关于WebView中controller.postUrl
HarmonyOS 鸿蒙Next中关于WebView中controller.postUrl 服务端收不到controller.postUrl(string,postData)请求的postData参数;一样的参数用安卓请求,服务端是能收到postData参数的
有人遇到过吗?有什么解决办法没有?
aboutToAppear(): void {
//加密字符串
this.req = 'gcO5Nrm/FH0BpGmGEfxGw1Wbpl/3xwigzPjOFnfJio30LCEVbhVTSX8HyOfodYRo3h2BbAliDtAvvXPAwVWvl/oLLhO6ob4bdvGi0bWilCylqdxj/O1ir7eM5BKEdqvWJAmUeKlxzdHALzuJc8iiBgYzZO9UA2jLoxRfCzsVLu3QFTT19u0p6tPGNFUzgZ1cOQ7z0IyWniIbgDN09PWejNz0tLufcmwSm8mM1HsOHD2H5z63zPByAajFn9otiNfpp5tIcqlT/ftg7L5i2FtQNYB4Tb/6y3Xv7y+fGHCN7OWXW4+BzGL+UmGsG5B6aQNYFV5HDBmdYdlYOr4fruIA7LhRHKpDCduS8ZHmHhikqvne8CFyNLD6b74X6L6eNVJ1zjZqB9WrscLkZvbRA+Xwk/9bbCUiOu7/aWi5K8lVXYQsrS46PDl0nhz5NOTWPLHphvyiAjdccRasoeKZotKTIB98R5RZEhVcp0K7YP0WSgayTp9Nuagk5EtPc/I3UfXkinfrN/TFEKY+VjXAIdihMq43D9FjywWE2HCfOLs+LejWXYufX6UKuhrcLTeHuJZWgTmKwcQVqY2R+9wwk6Ugrq7N89R9ilugngoulFA9uSiZn9PS3SsmsWCEwK/zvfyAc+ns1aj1vzZ67/JNthgo2tmnfSQTg5ZxFh+bDA4pKpz1Zps/J3s9/rf2sKAeAy38n20yqRanxkTI94+Ugz4waV4Fg2rwB2GmAqaj2WaVOg+WK3SHyoeP01nrqsIa3SaiH66yVIDQKV4kwodBal9NJEyyTy5dvODojfwk+uYp2KyE8HCbL3ktiulue1VhaHeohWcnfOBUF7H9djwTaKDxj8vWS+XhkxnxEoeX7dk8WuK3iRNctVhz/zTIFYVqfxJD'
this.targetUrl = 'https://sdk.tjyouxi.com/31793201354940523'
}
try {
let data2 =encodeURIComponent(this.req);
console.info(`url:${this.targetUrl},data:${this.test(data2)}`)
this.controller.postUrl(this.targetUrl, this.test(data2))
}catch (error){
const err = error as Error
console.info(`webview err:${err.message}`)
}
test(str: string): ArrayBuffer {
let buf = new ArrayBuffer(str.length);
let buff = new Uint8Array(buf);
for (let i = 0; i < str.length; i++) {
buff[i] = str.charCodeAt(i);
}
return buf;
}
更多关于HarmonyOS 鸿蒙Next中关于WebView中controller.postUrl的实战教程也可以访问 https://www.itying.com/category-93-b0.html
尊敬的开发者,您好,
使用postUrl接口时需要注意:
-
使用"POST"方法传递数据,该请求必须采用"application/x-www-form-urlencoded"编码。
-
postData的形式,请提供key=value形式的数据,然后将该key=value形式的数据转换为ArrayBuffer,如下:
"Name=test&Password=test"
您可以参考postUrl文档所提供的示例写法。
更多关于HarmonyOS 鸿蒙Next中关于WebView中controller.postUrl的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这里建议先检查两个点:
-
postUrl 的第二个参数官方定义是 ArrayBuffer,不是普通 string。
-
官方文档说明,POST 数据需要使用 application/x-www-form-urlencoded 编码;如果 URL 不是网络 URL,ArkWeb 会按 loadUrl 加载,并忽略 postData。
也就是说,服务端如果按表单参数读取,客户端需要把数据先组织成类似 key=value&key2=value2 的格式,再转换为 ArrayBuffer 传入,而不是直接传 JSON 字符串或密文原文。服务端也要按 application/x-www-form-urlencoded 方式接收。
依据:WebviewController.postUrl 官方文档:
HarmonyOS WebView postUrl 与 Android 行为差异
HarmonyOS 的 WebviewController.postUrl() 和 Android WebView 的行为并不完全一致。
你现在最大的问题其实是:
你传进去的 postData 不是标准的 application/x-www-form-urlencoded 格式。
HarmonyOS WebView 很可能不会像 Android 那样帮你兜底处理。
你现在实际传的是:
encodeURIComponent(this.req)
然后直接转 ArrayBuffer。
但服务端一般期望收到的是:
key=value
这种格式。
你现在少了参数名。
你现在发出去的实际上类似:
gcO5Nrm/FH0BpGmGEfx...
而不是:
data=gcO5Nrm%2FFH0BpGm...
所以很多后端框架会认为 POST Body 为空。
建议改成:
let postData = `data=${encodeURIComponent(this.req)}`;
this.controller.postUrl(
this.targetUrl,
postDataToArrayBuffer(postData)
);
然后:
function postDataToArrayBuffer(str: string): ArrayBuffer {
return new TextEncoder().encode(str).buffer;
}
不要再用:
charCodeAt
那个方式对中文、特殊字符、UTF8 都可能有坑。
你现在这个:
buff[i] = str.charCodeAt(i);
本质是按 UTF-16 写的,不是标准 HTTP POST UTF-8 字节流。
HarmonyOS WebView 对 POST 数据格式要求比 Android 更严格。
另外还有几个 HarmonyOS WebView 的坑:
1. postUrl 只能发 form-urlencoded
不能直接发:
- JSON
- Base64 二进制
- 自定义 Body
官方行为和 Android 一样,本质是:
application/x-www-form-urlencoded
格式。
所以如果后端要求:
{
"data":"xxx"
}
那 postUrl() 基本不适合。
建议改:
fetch()
或者:
@ohos.net.http
请求后:
controller.loadData()
2. HarmonyOS WebView 可能不自动带 Content-Type
有些服务端会因为没有:
Content-Type: application/x-www-form-urlencoded
直接忽略 body。
Android WebView 有时会自动补。
HarmonyOS 不一定。
所以很多人最后改成:
httpRequest.request(...)
然后:
webview.loadData()
绕过 postUrl。
3. 超长 POST 数据可能被 HarmonyOS WebView 截断
你这个加密串太长了。
HarmonyOS NEXT 的 WebView 内核目前确实有人反馈:
- 超长 body
- base64 body
- 二进制 body
会出现:
- body 丢失
- 服务端收不到
- 自动变 GET
的问题。
尤其是:
postUrl(url, ArrayBuffer)
这里兼容性不如 Android。
所以你这个场景,我其实更建议:
最稳方案
别用:
controller.postUrl()
改:
http.createHttp()
先请求接口:
POST
拿到 HTML 后:
controller.loadData()
或者:
controller.loadUrl()
这是 HarmonyOS 里目前最稳定的做法。
你现在这个场景很像:
- SDK鉴权
- 游戏登录
- 支付跳转
这种场景 HarmonyOS WebView 的 postUrl 确实坑比较多。
最后给你一个 HarmonyOS NEXT 可用版本:
import web_webview from '@ohos.web.webview';
let postData = `data=${encodeURIComponent(this.req)}`;
let buffer = new TextEncoder().encode(postData).buffer;
this.controller.postUrl(
this.targetUrl,
buffer
);
如果服务端还是收不到:
那基本就不是你代码问题了。
而是 HarmonyOS WebView 内核对 POST Body 的兼容问题。
直接换:
@ohos.net.http
是最终解。
是不是编码问题导致的;使用"POST"方法传递数据。 该请求必须采用"application/x-www-form-urlencoded"编码。检查下服务端是否有报错日志
在HarmonyOS Next中,WebviewController的postUrl(url: string, postData: ArrayBuffer): void用于向指定URL发送POST请求并加载响应。postData需转换为ArrayBuffer(如new ArrayBuffer())。需确保已获取webview组件并绑定控制器。
问题出在 postUrl 第二个参数需传入 ArrayBuffer,但服务端解析时需匹配 Content-Type。你的代码直接将整个经 encodeURIComponent 处理过的字符串转为 ArrayBuffer 整体发送,服务端若按 application/x-www-form-urlencoded 解析,无法识别为键值对格式,因此 postData 丢失。
修正:构造 key=value 格式的表格数据再转为 ArrayBuffer。
let postData = 'data=' + encodeURIComponent(this.req); // 键值对格式
let buf = new ArrayBuffer(postData.length);
let buff = new Uint8Array(buf);
for (let i = 0; i < postData.length; i++) {
buff[i] = postData.charCodeAt(i);
}
this.controller.postUrl(this.targetUrl, buf);
另外,若服务端要求 JSON 格式,直接将 JSON 字符串转为 ArrayBuffer 并设置请求头 Content-Type: application/json,但 postUrl 无法直接设头,可改用 loadUrl 配合请求拦截。此修复仅针对表格数据场景。

