Unity集成bKash支付网关时特殊字符密码的请求头报错解决
解决方案:Unity中bKash API密码含特殊字符导致请求失败
问题原因
Unity的UnityWebRequest.SetRequestHeader方法会严格校验HTTP头值的字符合法性,你的密码包含"和)这类字符,被Unity判定为无效字符,因此抛出InvalidOperationException。而Postman没有执行同样严格的校验,能直接发送原始密码,所以请求正常。
可行解决方案
方案1:直接修改Headers字典绕过校验
Unity的SetRequestHeader会做字符校验,但直接操作request.headers字典可以绕过这一步。把设置密码头的代码替换为:
// 替换原来的SetRequestHeader request.headers["password"] = _bkashData.password ?? "";
这样就能直接将包含特殊字符的密码写入请求头,无需编码。
方案2:对密码进行百分编码
如果方案1无效,可将密码中的特殊字符按HTTP标准进行百分编码,再传入请求头。编写一个编码辅助函数:
private string EncodeHeaderSpecialChars(string input) { // 对所有非ASCII或特殊字符进行编码 return Uri.EscapeDataString(input); }
然后修改密码头的设置:
request.SetRequestHeader("password", EncodeHeaderSpecialChars(_bkashData.password ?? ""));
编码后的密码会将"转为%22,)转为%29,Unity会接受这个合法的字符串,同时bKash服务器通常能自动解码获取原始密码。
方案3:切换到System.Net.Http客户端(需.NET 4.x+)
如果上述方案都不生效,可改用System.Net.Http库,它对请求头的校验更宽松。注意需要在Unity Player设置中把脚本运行时版本切换为.NET 4.x Equivalent。示例代码:
private async Task CallApiWithHttpClient(string api, string json, Action<string> onResponse) { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("username", _bkashData.username ?? ""); client.DefaultRequestHeaders.Add("password", _bkashData.password ?? ""); client.DefaultRequestHeaders.Add("X-App-Key", _bkashData.appkey ?? ""); client.DefaultRequestHeaders.Add("Authorization", _token ?? ""); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await client.PostAsync(api, content); if (response.IsSuccessStatusCode) { string responseText = await response.Content.ReadAsStringAsync(); onResponse(responseText); } else { AppUtils.PrintLog($"bKash Api Failed: {response.ReasonPhrase} | API: {api} | Request: {json}"); } } }
验证建议
优先尝试方案1,因为它最简单且不需要修改密码格式。如果方案1无效,再尝试方案2。方案3作为最后备选,因为涉及到运行时版本的切换。
内容的提问来源于stack exchange,提问作者Siddharth Mehra
相关产品推荐
相关产品推荐

