GET请求在Postman中正常但浏览器及Android端调用失败如何解决
问题原因分析
- 核心原因1:接口鉴权依赖自定义请求头,浏览器、安卓代码均未携带Postman中配置的
User、Password、Device等必填头参数,请求被服务端直接拦截。 - 核心原因2:安卓端使用HTTP明文请求,安卓9(API 28)及以上系统默认禁止明文HTTP传输,请求会被系统直接截断。
- 核心原因3:现有Retrofit代码缺少错误处理逻辑,空值强制取值会直接触发崩溃,也无法排查具体错误信息。
具体修复方案
1. 给Retrofit请求添加必填头参数
两种方案可选,全局统一添加更方便:
方案A:使用拦截器全局添加头
fun getRetrofit(): Retrofit { // 新建拦截器添加统一请求头 val headerInterceptor = Interceptor { chain -> val original = chain.request() val requestBuilder = original.newBuilder() .addHeader("Content-Type", "application/json") .addHeader("User", "Dermacycle2018") .addHeader("Password", "你的实际密码") .addHeader("Device", "你对应的设备标识") .addHeader("VersionSO", "你的系统版本") .addHeader("VersionAPP", "1.0.1") .method(original.method, original.body) chain.proceed(requestBuilder.build()) } // 构建OkHttpClient并添加拦截器 val okHttpClient = OkHttpClient.Builder() .addInterceptor(headerInterceptor) .build() return Retrofit.Builder() .baseUrl("http://dermaservice.theappmaster.com/") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() }
方案B:直接在接口上标注头
interface DermaCycleApiClient { @Headers( "Content-Type: application/json", "User: Dermacycle2018", "Password: 你的实际密码", "Device: 你对应的设备标识", "VersionSO: 你的系统版本", "VersionAPP: 1.0.1" ) @GET suspend fun getTratamientosFaciales(@Url url: String): Response<TratamientosFacialesResponse> }
2. 处理安卓HTTP明文限制
优先建议联系接口提供方升级为HTTPS协议,若临时测试可通过配置解除限制:
在res/xml目录下新建network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">dermaservice.theappmaster.com</domain> </domain-config> </network-security-config>
然后在AndroidManifest.xml的application节点添加配置:
<application ... android:networkSecurityConfig="@xml/network_security_config" ...> </application>
3. 优化请求错误处理
修改请求逻辑,避免空指针崩溃,同时可打印错误码排查问题:
suspend fun getTratamientosFaciales(tf: String): TratamientosFacialesResponse? { return withContext(Dispatchers.IO) { val response = retrofit.create(DermaCycleApiClient::class.java) .getTratamientosFaciales("Tratamiento.ashx?Tipo=TF") // 已经配置baseUrl不需要写全地址 if (response.isSuccessful) { response.body() } else { // 可打印response.code()、response.errorBody()排查错误 null } } }
浏览器测试说明
浏览器直接输入地址只会携带默认请求头,不会自动添加自定义鉴权头,可安装Header修改类插件添加对应User、Password等参数后再测试,即可得到和Postman一致的结果。
内容的提问来源于stack exchange,提问作者Rob Aberan
相关产品推荐
相关产品推荐

