16

大家好,在使用 Visual Studio 2008 (Cassini) 在内置 Web 服务器上本地测试 ASP.NET 应用程序时,我似乎发现了一个差异。

我已经在本地机器上设置了一个主机,将dev.testhost.com127.0.0.1关联起来,因为我有一个应用程序需要根据用于调用它的主机标头来更改其外观。

但是,当我使用 请求我的测试应用程序时http://dev.testhost.com:1234/index.aspx, 的值Request.Url.Host始终是"localhost"。而 is 的值Request.Headers["host"]"dev.testhost.com:1234"正如我所期望那样)。

我不担心第二个值包括端口号,但我很困惑为什么主机名完全不同!有谁知道这是一个已知问题还是设计使然?还是我是个白痴?!

我宁愿使用Request.Url.Host,因为这样可以避免在测试时必须去掉端口号... -由于可能引起混淆而被删除!- 山姆

4

3 回答 3

9

Request.Headers["host"]是从连接到服务器的应用程序接收到的值,而另一个值是服务器在尝试获取域名时获取的值。

浏览器在请求中使用输入的域名,因为这是在虚拟域的情况下使用的。服务器报告服务器首选项中的一组,或者它找到的第一个。

编辑:查看 Cassini 的代码以查看它是否使用某些特定设置,我注意到以下代码:

public string RootUrl {
  get {
    if (_port != 80) {
      return "http://localhost:" + _port + _virtualPath;
    }
    else {
      return "http://localhost" + _virtualPath;
    }
  }
}

//
// Socket listening
//

public void Start() {
  try {
    _socket = CreateSocketBindAndListen(AddressFamily.InterNetwork, IPAddress.Loopback, _port);
  }
  catch {
    _socket = CreateSocketBindAndListen(AddressFamily.InterNetworkV6, IPAddress.IPv6Loopback, _port);
  }
  // …
}

解释似乎是 Cassini 明确引用了 localhost,并没有尝试进行反向 DNS 查找。不同的是,它不会使用return "http://localhost" + _virtualPath;.

于 2009-12-21T17:48:07.760 回答
8

Request.Headers["host"]是在浏览器的 http 标头中指定的主机。(例如,如果您使用 Fiddler 或 HttpWatch 检查流量,这就是您所看到的)

但是,ASP.NET 将此(和其他请求信息)加载到一个System.Uri实例中,该实例将请求字符串解析为其组成部分。在这种情况下,“主机”实际上是指原始请求的主机部分(例如,tcp 端口位于端口中)属性。

这个System.Uri类是一个非常有用的帮助类,它消除了将请求拆分成各个部分的所有痛苦,而来自 http 标头的“Host:”(以及就此而言的“GET”)只是原始请求数据。

尽管它们都具有相同的名称,但它们并不意味着相同。

于 2009-12-21T17:48:21.740 回答
1

这是w3 规范所说的内容与 Microsoft Uri.Host属性应该包含的内容的问题。命名并不意味着 MS 试图提供相同的功能。包含端口号的函数是Uri.Authority

随着您发布的更新,您仍然面临同样的问题,只是检查它的不同方面。Uri.Host属性没有明确或暗示执行与 w3 规范中定义的标头相同的功能。以下是来自 Uri.Host MSDN 页面的一些引文:

Uri.Host 属性
获取此实例的主机组件。

适当的价值

类型:System.String

包含主机名的字符串。这通常是服务器的 DNS 主机名或 IP 地址。

不能保证这将匹配标头中的内容,只是它以某种形式表示主机名。

于 2009-12-21T17:44:37.673 回答