我需要将数据发布到服务器(带有“referer”标题字段)并在Webview中加载响应。
现在,有不同的方法(来自Android WebView)来完成部分内容,例如:
void loadUrl(String url, Map<String, String> additionalHttpHeaders)
使用指定的其他HTTP标头加载给定的URL。
void loadData(String data, String mimeType, String encoding)
使用“数据”方案URL将给定数据加载到此WebView中。
void postUrl(String url, byte[] postData)
使用“POST”方法将带有postData的URL加载到此WebView中。
loadUrl()允许发送HttpHeaders但不允许发送post数据,其他方法似乎不允许发送HttpHeaders。我错过了什么或者我正在尝试的是不可能的吗?
答案 0 :(得分:1)
您可以像这样手动执行HttpPost
:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/postreceiver");
// generating your data (AKA parameters)
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("ParameterName", "ParameterValue"));
// ...
// adding your headers
httppost.setHeader("HeaderName", "HeaderValue");
// ...
// adding your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
获取response
String
:
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
String html = builder.toString();
现在,您可以使用html
将yourWebView
加入loadData()
:
yourWebView.loadData(html ,"text/html", "UTF-8");
答案 1 :(得分:0)
您可以使用继承自 WebView 的自定义类,或者如果您愿意,可以添加扩展功能。逻辑基本相同:
private fun WebView.postUrl(postUrl: String, postData: ByteArray, additionalHttpHeaders: MutableMap<String, String>) {
val savedWebViewClient = getWebViewClient()
webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
if (url != postUrl) {
view.post {
webViewClient = savedWebViewClient
}
return savedWebViewClient?.shouldInterceptRequest(view, url)
}
Log.d("WebView extension", "post ${postData.decodeToString()} to ${url}")
val httpsUrl = URL(url)
val conn: HttpsURLConnection = httpsUrl.openConnection() as HttpsURLConnection
conn.requestMethod = "POST"
additionalHttpHeaders.forEach { header ->
conn.addRequestProperty(header.key, header.value)
}
conn.outputStream.write(postData)
conn.outputStream.close()
val responseCode = conn.responseCode
Log.d("WebView extension", "responseCode = ${responseCode} ${conn.contentType}")
view.post {
webViewClient = savedWebViewClient
}
// typical conn.contentType is "text/html; charset=UTF-8"
return WebResourceResponse(conn.contentType.substringBefore(";"), "utf-8", conn.inputStream)
}
}
loadUrl(postUrl, additionalHttpHeaders)
}
为了简洁起见,对上面的代码进行了编辑,隐藏了大多数错误检查。为了处理低于 26 级的 API,我使用反射来提取 savedWebViewClient
。
在现实生活中,您还希望覆盖新的 shouldInterceptRequest(view: WebView, request: WebResourceRequest)
方法,并将 WebViewClient 的所有其他方法委托给 savedWebViewClient
。可能 PostWithHeadersWebView 类(也覆盖 setWibViewClient()
)可以让您的生活更轻松。