1. WebViewClientの shouldInterceptRequest()を書き換えてリクエストをインターセプトし、特殊な処理(クロスドメイン処理)を実装します。
たとえば、古い URL をインターセプトし、ドメイン名、パラメータなどを置き換えてから、新しい URL を使用してリクエストを再開始します。
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
request.url.toString().let {
// 判断该请求是否需要拦截处理
if (it.contains("xxx")) {
return assembleResponse(view, request)
}
}
//此处代表拦截器不处理该请求,直接原路请求器处理
return super.shouldInterceptRequest(view, request)
}
2. WebResourceResponse をアセンブルします。
/**
* 手动组装response
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun assembleResponse(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
try {
val originUrl = request.url.toString()
val realUrl = getRealUrl(originUrl)
// val headers = request.requestHeaders
val response = doGet(realPath, null).execute()
if (response.isSuccessful && response.code() == 200) {
return response.body()?.run {
WebResourceResponse(
response.header("Content-Type"),
response.header("Content-Encoding"),
response.body()?.byteStream()
)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
3. ネットワークリクエスト – 以下を取得します。
private fun addHeader(builder: Request.Builder, headers: JSONObject?) {
if (headers != null) {
val keys = headers.keys()
while (keys.hasNext()) {
val key = keys.next()
val value = headers.optString(key, "")
builder.addHeader(key, value)
}
}
}
fun doGet(url: String?, headers: JSONObject?): Call? {
var client: OkHttpClient? = null
val trustManager = HttpUtils.getX509TrustManager()
val okhttpBuilder = OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS) // okhttp 已经有RetryAndFollowUpInterceptor
.hostnameVerifier(HttpUtils.TrustAllHostnameVerifier())
.addNetworkInterceptor(RemoveDirtyConnIntercepter())
.sslSocketFactory(SSLSocketFactoryCompat(trustManager), trustManager)
client = okhttpBuilder.build()
val builder = Request.Builder().url(url)
addHeader(builder, headers)
val request = builder.get()
.build()
return client.newCall(request)
}