如何让 iOS 和 Android 强制所有 http/s 请求通过代理?本地化到应用程序,而不是整个操作系统?
我已经在 Android 上试过了,但它不适用于 Https:
JavaSystem.setProperty("http.proxyHost", <your proxy host name>);
JavaSystem.setProperty("http.proxyPort", <your proxy port>);
JavaSystem.setProperty("https.proxyHost", <your proxy host name>);
JavaSystem.setProperty("https.proxyPort", <your proxy port>);
对于 Android,我也尝试过实现 WebClient 并覆盖 shouldoverrideurlloading 但 Xamarin 似乎对 HttpWebRequest 和 https 调用有问题,提示
Error: SecureChannelFailure (The authentication or decryption has failed.)"
最佳答案
不幸的是,覆盖 WebClient shouldInterceptRequest 有一些问题,例如拦截 html 以外的任何内容,但我设法通过这种方式解决了我的问题:
public class DawgWebViewClient: WebViewClient
{
private class DawgWebResourceResponse : WebResourceResponse
{
IWebResourceRequest baseRequest;
public DawgWebResourceResponse(IWebResourceRequest request) : base(null, null, null)
{
this.baseRequest = request;
this.LoadRequestAsync();
}
ManualResetEvent responseDataWaiter = new ManualResetEvent(false);
ManualResetEvent metaDataWaiter = new ManualResetEvent(false);
private void LoadRequestAsync()
{
Task.Run(async () =>
{
HttpClient client = new HttpClient(new ModernHttpClient.NativeMessageHandler());
foreach(var header in this.baseRequest.RequestHeaders)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
HttpResponseMessage response;
switch(this.baseRequest.Method)
{
case "GET":
response = await client.GetAsync(this.baseRequest.Url.ToString());
break;
default:
response = null;
Debugger.Break();
break;
}
string
mediaType = response.Content.Headers.ContentType?.MediaType ?? "*/*",
charSet = response.Content.Headers.ContentType?.CharSet ?? "UTF-8";
this.MimeType = mediaType;
this._statusCode = (int)response.StatusCode;
this.ResponseHeaders = response.Headers.ToDictionary(y => y.Key, y => y.Value.FirstOrDefault());
metaDataWaiter.Set();
this.Data = await response.Content.ReadAsStreamAsync();
responseDataWaiter.Set();
});
}
public override Stream Data
{
get {
this.responseDataWaiter.WaitOne();
return base.Data;
}
set
{
base.Data = value;
}
}
public override IDictionary<string, string> ResponseHeaders
{
get
{
this.metaDataWaiter.WaitOne();
return base.ResponseHeaders;
}
set
{
base.ResponseHeaders = value;
}
}
private int _statusCode = 0;
public override int StatusCode
{
get
{
this.metaDataWaiter.WaitOne();
return this._statusCode;
}
}
public override string Encoding
{
get
{
this.metaDataWaiter.WaitOne();
return base.Encoding;
}
set
{
base.Encoding = value;
}
}
public override string ReasonPhrase
{
get
{
this.metaDataWaiter.WaitOne();
return base.ReasonPhrase;
}
}
public override string MimeType
{
get
{
this.metaDataWaiter.WaitOne();
return base.MimeType;
}
set
{
base.MimeType = value;
}
}
}
public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
{
if(request.RequestHeaders["Accept"]?.Contains("text/html") == true) return new DawgWebResourceResponse(request);
return null;
}
}
关于c# - Xamarin Forms WebView 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44709920/