[英]CefSharp 3 set proxy at Runtime
我下載了(cefclient & cefsimple)c++ 示例附帶的 CEF(chromuim 嵌入式框架)二進制分發,並意識到 cefclient 可以在運行時更改代理設置。
關鍵是獲取 RequestContext 並調用 function SetPreference。
在 CefClient 上一切正常。
但是在 CefSharp 調用 SetPreference 總是返回 false,並且 HasPreference 也為首選項名稱“代理”返回 false。
感謝amaitland主動強制更改請求上下文偏好的正確方法是在 CEF UIThread 上運行代碼,如下所示:
Cef.UIThreadTaskFactory.StartNew(delegate {
var rc = this.browser.GetBrowser().GetHost().RequestContext;
var v = new Dictionary<string, object>();
v["mode"] = "fixed_servers";
v["server"] = "scheme://host:port";
string error;
bool success = rc.SetPreference("proxy", v, out error);
//success=true,error=""
});
如果有人需要任何其他靈魂,我找到了這個解決方案。
Cef.UIThreadTaskFactory.StartNew(delegate
{
string ip = "ip or adress";
string port = "port";
var rc = this.browser.GetBrowser().GetHost().RequestContext;
var dict = new Dictionary<string, object>();
dict.Add("mode", "fixed_servers");
dict.Add("server", "" + ip + ":" + port + "");
string error;
bool success = rc.SetPreference("proxy", dict, out error);
});
我下載了 CefSharp.WinForms 65.0.0 並創建了類,這有助於開始使用代理:
public class ChromeTest
{
public static ChromiumWebBrowser Create(WebProxy proxy = null, Action<ChromiumWebBrowser> onInited = null)
{
var result = default(ChromiumWebBrowser);
var settings = new CefSettings();
result = new ChromiumWebBrowser("about:blank");
if (proxy != null)
result.RequestHandler = new _requestHandler(proxy?.Credentials as NetworkCredential);
result.IsBrowserInitializedChanged += (s, e) =>
{
if (!e.IsBrowserInitialized)
return;
var br = (ChromiumWebBrowser)s;
if (proxy != null)
{
var v = new Dictionary<string, object>
{
["mode"] = "fixed_servers",
["server"] = $"{proxy.Address.Scheme}://{proxy.Address.Host}:{proxy.Address.Port}"
};
if (!br.GetBrowser().GetHost().RequestContext.SetPreference("proxy", v, out string error))
MessageBox.Show(error);
}
onInited?.Invoke(br);
};
return result;
}
private class _requestHandler : DefaultRequestHandler
{
private NetworkCredential _credential;
public _requestHandler(NetworkCredential credential = null) : base()
{
_credential = credential;
}
public override bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
if (isProxy == true)
{
if (_credential == null)
throw new NullReferenceException("credential is null");
callback.Continue(_credential.UserName, _credential.Password);
return true;
}
return false;
}
}
}
使用:
var p = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
var p1 = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
var p2 = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
wb1 = ChromeTest.Create(p1, b => b.Load("http://speed-tester.info/check_ip.php"));
groupBox1.Controls.Add(wb1);
wb1.Dock = DockStyle.Fill;
wb2 = ChromeTest.Create(p2, b => b.Load("http://speed-tester.info/check_ip.php"));
groupBox2.Controls.Add(wb2);
wb2.Dock = DockStyle.Fill;
wb3 = ChromeTest.Create(p, b => b.Load("http://speed-tester.info/check_ip.php"));
groupBox3.Controls.Add(wb3);
wb3.Dock = DockStyle.Fill;
如果您想要動態代理解析器(代理處理程序),它允許您為不同的主機使用不同的代理 - 您應該:
1) 准備javascript
var proxy1Str = "PROXY 1.2.3.4:5678";
var proxy2Str = "PROXY 2.3.4.5:6789";
var ProxyPacScript =
$"var proxy1 = \"{(proxy1Str.IsNullOrEmpty() ? "DIRECT" : proxy1Str)}\";" +
$"var proxy2 = \"{(proxy2Str.IsNullOrEmpty() ? "DIRECT" : proxy2Str)}\";" +
@"function FindProxyForURL(url, host) {
if (shExpMatch(host, ""*example.com"")) {
return proxy1;
}
return proxy2;
}";
var bytes = Encoding.UTF8.GetBytes(ProxyPacScript);
var base64 = Convert.ToBase64String(bytes);
2)正確設置
var v = new Dictionary<string, object>();
v["mode"] = "pac_script";
v["pac_url"] = "data:application/x-ns-proxy-autoconfig;base64," + base64;
3)按照接受的答案調用 SetPreference https://stackoverflow.com/a/36106994/9252162
結果,所有對 *example.com 的請求都將通過 proxy1,所有其他請求都通過 proxy2。
為此,我花了一整天的時間,但在來源 ( https://cs.chromium.org/ ) 的幫助下,我找到了解決方案。 希望它可以幫助某人。
主要問題:
1)在新版本(我記得是 72 或 74)中,無法使用“file://...”作為 pac_url。
2) 我們不能在 cef 中使用https://developer.chrome.com/extensions/proxy .. 或者我找不到怎么做。
ps 如何使用其他類型的代理(https、socks) - https://chromium.googlesource.com/chromium/src/+/master/net/docs/proxy.md#evaluating-proxy-lists-proxy-fallback
使用新版本的 CefSharp,設置代理非常簡單:
browser = new ChromiumWebBrowser();
panel1.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
await browser.LoadUrlAsync("about:blank");
await Cef.UIThreadTaskFactory.StartNew(() =>
{
browser.GetBrowser().GetHost().RequestContext.SetProxy("127.0.0.1", 1088, out string _);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.