Unity打包Android调用Hasura遇Curl 60错误及解析失败求助
Unity打包Android后调用Hasura HTTP端点出现证书错误+Query缺失问题解决
问题描述
- Unity编辑器内调用Hasura GraphQL查询可正常返回列表数据
- 打包至Android设备后触发两个异常:
- Curl错误:
Curl error 60: Cert verify failed: UNITYTLS_X509VERIFY_FLAG_USER_ERROR1 - 返回错误响应:
{"errors":[{"extensions":{"code":"parse-failed","path":"$"},"message":"the key 'query' was not present"}]}
- Curl错误:
- 环境说明:Hasura使用HTTP而非HTTPS端点,数据库为PostgreSQL
- 已尝试无效操作:切换端点协议为HTTP、覆盖RSA证书、请求时禁用SSL
解决方案
1. 允许Android明文HTTP请求(解决证书验证错误)
Android 9及以上系统默认限制明文HTTP流量,即使你用的是HTTP端点,也会被系统拦截触发证书验证错误。需通过配置解除限制:
- 在Unity项目的
Assets/Plugins/Android目录下创建(或修改)AndroidManifest.xml,添加网络安全配置声明:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools"> <application android:networkSecurityConfig="@xml/network_security_config" tools:replace="android:networkSecurityConfig"> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> </application> </manifest>
- 在
Assets/Plugins/Android/res/xml目录下创建network_security_config.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>
- 检查Unity
Player Settings->Android->Other Settings,确保Internet Access设置为Require或Auto
2. 修正Hasura请求格式(解决query字段缺失错误)
编辑器正常但打包后异常,大概率是请求体编码或请求头配置问题导致Hasura无法识别query字段:
- 强制设置请求头
Content-Type: application/json,Hasura仅识别此格式的JSON请求体 - 确保请求体严格包含
query键,示例正确JSON结构:
{ "query": "query GetItems { items { id name } }" }
- 使用
UnityWebRequest时,需用UploadHandlerRaw传递正确序列化的JSON字节,示例代码:
IEnumerator FetchHasuraData() { string graphqlQuery = "{\"query\":\"query GetItems { items { id name } }\"}"; byte[] requestBody = System.Text.Encoding.UTF8.GetBytes(graphqlQuery); UnityWebRequest request = UnityWebRequest.Post("http://your-hasura-endpoint/v1/graphql", "POST"); request.SetRequestHeader("Content-Type", "application/json"); request.uploadHandler = new UploadHandlerRaw(requestBody); request.downloadHandler = new DownloadHandlerBuffer(); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogError($"请求失败:{request.error}"); } else { Debug.Log($"返回数据:{request.downloadHandler.text}"); } }
- 避免将GraphQL query放在URL参数中,Hasura的标准端点仅接受POST请求体中的query参数
3. 强制禁用SSL验证(测试环境应急方案)
如果以上方法无效,可临时禁用Unity的SSL证书验证(仅用于测试,生产环境禁止使用):
- 在发起请求前添加代码:
#if UNITY_ANDROID UnityEngine.Networking.UnityWebRequest.disableCertificateValidation = true; #endif
- 或在Unity
Player Settings->Android->Other Settings->Configuration中,找到SSL Certificate Validation并设置为Disabled(不同Unity版本位置可能略有差异)
内容的提问来源于stack exchange,提问作者Nguyen Gia Son
相关产品推荐
相关产品推荐

