2

最终,我想阻止 .NET WebBrowser 控件中的下载,有效地将其限制为显示 HTML、图像、脚本等,但永远不会用户显示“另存为”对话框。

在回答该问题时提出的解决方案是连接一个自定义代理服务器,该服务器检查响应并过滤掉任何会导致下载提示的内容。如何在我的 .NET 应用程序中实现这样的代理?我不想安装第三方软件或库。

我找到了HttpListener 类,但我遇到了两个问题:

  1. 侦听器需要一组预定义的前缀来触发它。但是,我不希望在我的应用程序中硬编码主机名或端口号,并保持其通用性。
  2. 我必须自己实现执行实际请求的代码 - 是不是有什么东西可以为我做这件事,我可以简单地点击该行,检查响应的内容并根据需要更改它们(如请求过滤器J2EE 在服务器端做)?

更新

好的,我想我需要更清楚一点:我的 .NET(富客户端)应用程序正在多个项目中使用,这些项目也有基于 Web 的应用程序。.NET 应用程序包括一个带有 WebBrowser 控件的可重复使用的通用表单。其他开发人员使用该表单将对其 Web 应用程序的访问集成到 .NET 应用程序中。

我想阻止下载,所以我想让我的 WebBrowser 表单拦截所有流量并确保它不会导致“另存为”对话框。因此...

  • 我不知道主机名是什么
  • WebBrowser 指向真实的 URL,用户点击常规链接,触发 JavaScript……所有这些都由 Web 应用程序提供
  • 如果 WebBrowser 指向 localhost(如建议的那样),我必须解析响应并重写所有链接,以便它们再次指向 localhost,保留原始 URL。我不想经历那个麻烦。
4

2 回答 2

5

HttpListener应该没问题,但它只是 http.sys 的包装,而且这个库仅在 Windows XP 和更高版本上可用。

Http前缀

您只需要一个前缀http://127.0.0.1:8080/,因为它仅适用于您的本地 web 控件。或者,支持通配符,http://*:8080/但没有理由在您的情况下使用它。

延斯班曼写道:

访问的应用程序不在localhost,它们可以在任何地方。这就是为什么我不想硬编码任何东西。

你说的应用是什么意思?你是说网站吗?这完全是另一回事,您的特殊代理服务器将在 HttpListenerRequests 上侦听http://127.0.0.1:8080/,因此您的 webcontrol 必须使用代理服务器http://127.0.0.1:8080/。此时它仍然在本地机器中。

在 HttpListenerRequest/Response 和 HttpWebRequest/Response 之间转换

将每个传入转换HttpListenerRequestHttpWebRequest,请求响应,您将获得HttpWebResponse对象,分析它是否允许您的 WebBrowser 控件响应,如果是,则将其写入HttpListnererResponse对象,否则写入其他内容(错误状态)。

这可能是在 .NET 上构建自己的代理服务器的最简单方法

延斯班曼写道:

对,这种转换是我想要避免做的事情。或者我可以只用几行代码来做到这一点吗?从 API 来看,它看起来更复杂。

这实际上很容易,因为 http 协议很简单。它基本上分为三个部分。

  • 请求行(它包含 URL、http 方法和 http 版本)
  • 标头(这实际上是使 API 看起来如此庞大和重要的原因,但实际上所有这些属性和方法都只是原始 http 标头之上的薄层。您需要做的就是以通用方式直接将所有标头HttpListenerRequest从 复制到中HttpWebRequest。这两个类都有用于原始访问的通用Headers属性)
  • 消息正文(如果有,只需复制其内容)

整个转换看起来像这样:

HttpListenerRequest listenerRequest;

WebRequest webRequest = WebRequest.Create(listenerRequest.Url);
webRequest.Method = listenerRequest.HttpMethod;
webRequest.Headers.Add(listenerRequest.Headers);
byte[] body = new byte[listenerRequest.InputStream.Length];
listenerRequest.InputStream.Read(body, 0, body.Length);
webRequest.GetRequestStream().Write(body, 0, body.Length);

WebResponse webResponse = webRequest.GetResponse();

如果您需要有关 http 协议的更多帮助,请参阅此维基百科文章

您还可以查看此开源项目以了解另一种方法。它不依赖于HttpListener类,但它是完整的代理服务器解决方案,应该很容易根据您的需要进行修改。

于 2009-02-03T11:39:57.703 回答
0

也许是一个开源代理?

http://www.mentalis.org/soft/projects/proxy/

于 2009-02-03T13:17:20.377 回答