20

我知道以前有过一些关于这方面的讨论,但我已经尝试了所有建议的(我能找到的),到目前为止没有任何东西对我有用......

考虑到这一点,这就是我想要做的:

首先,我想允许用户发布页面并给他们每个他们选择的子域(例如:user.mysite.com)。据我所知,最好的方法是使用 mod_rewrite 和 .htaccess 将 user.mysite.com 映射到 mysite.com/user - 对吗?

如果这是正确的,有人可以给我关于如何做到这一点的明确说明吗?

另外,我在本地使用 MAMP 进行所有开发,所以如果有人能告诉我如何设置我的本地环境以相同的方式工作(我读过这更难),我将不胜感激。老实说,我一直在尝试一切都无济于事,因为这是我第一次做这样的事情,我完全迷失了。非常感谢您的帮助!

更新: 其中一些答案真的很有帮助,但对于我想到的系统,为每个用户手动添加子域不是一种选择。我真正要问的是如何即时执行此操作,并将 wildcard.mysite.com 重定向到 mysite.com/wildcard——Tumblr 的设置方式是我想做的一个完美示例。再次感谢!

4

8 回答 8

16

至于如何设置 DNS 子域通配符,这将是您的 DNS 托管服务提供商的一项功能。这将是不同的步骤,具体取决于您拥有的托管服务提供商,这对他们来说是一个更好的问题。

一旦你用 DNS 主机设置了它,从你的 web 应用程序中你实际上只是 URL 重写,这可以通过 web 服务器本身的某种模块来完成,例如 isapi rewrite 如果你在 IIS 上(这个如果可能,将是首选路线)。您还可以在应用程序级别处理重写(例如在 ASP.NET 上使用路由)。

您将重写 URL,因此http://myname.domain.com将变为http://domain.com/something.aspx?name=myname或其他内容。从那里开始,您只需像平常一样处理 myname 值在查询字符串中一样。那有意义吗?希望我没有误解你在追求什么。

编辑:

我并不是建议您为每个用户创建一个子域,而是为域本身创建一个通配符子域,因此任何.domain.com(基本上是 *.domain.com)都会进入您的站点。我用mydomain设置了几个域。他们的设置说明如下:

是的,您可以配置通配符,但只有将其设置为 A 记录时才会起作用。通配符不适用于 C 名称。要使用通配符,请使用星号字符“*”。例如,如果您使用通配符.domain.com 创建和记录,则在“ ”所在位置输入的任何内容都将解析为指定的 IP 地址。因此,如果您在域名前输入“www”、“ftp”、“站点”或其他任何内容,它将始终解析为 IP 地址

我有一些是以这种方式设置的,让 *.domain.com 访问我的站点。然后,我可以在我的 Web 应用程序中读取基本 URL,以查看 ryan.domain.com 是当前访问的内容,或者 bill.domain.com 是已使用的内容。然后我可以:

  1. 使用 URL 重写,以便子域成为查询字符串的一部分或
  2. 只需从访问的 URL 中读取主机值并根据该值执行一些逻辑。

那有意义吗?我有几个站点以这种确切的方式设置:使用 DNS 主机为域创建通配符,然后简单地从 URL 中读取主机或基域,以根据子域(实际上是用户名)决定显示什么)

编辑2:

如果没有 DNS 条目,就无法做到这一点。“在线世界”需要知道 name1.domain.com、name2.domain.com、...、nameN.domain.com 都指向您服务器的 IP 地址。执行此操作的唯一方法是使用适当的 DNS 条目。您必须使用您的 DNS 主机为您的域添加通配符 DNS 条目。然后,您只需从 URL 中读取子域并在代码中采取适当的操作即可。

于 2008-09-17T03:55:11.773 回答
13

如果您正在运行 *AMP,最好的做法是按照 Thomas 的建议在 Apache 中做虚拟主机。您可以使用或不使用您描述的重定向来执行此操作。

虚拟主机

很可能您会想做基于名称的虚拟主机,因为它最容易设置并且只需要一个 IP 地址(因此也很容易在本地 MAMP 机器上设置和测试)。基于 IP 的虚拟主机在其他一些方面更好,但您必须为每个域设置一个 IP 地址。

这个Wikipedia 页面在底部讨论了如何进行基于名称的虚拟主机的差异和链接。

在您的本地机器上进行测试,您还必须在 /etc/hosts 中为您的假测试域名设置假 DNS 名称。即,如果您有 Apache 在 localhost 上侦听并在您的 Apache 配置中设置 vhost1.test.domain 和 vhost2.test.domain,您只需将这些域添加到 /etc/hosts 中的 127.0.0.1 行,在 localhost 之后:

127.0.0.1 localhost vhost1.test.domain vhost2.test.domain

一旦你完成了 /etc/hosts 编辑并将基于名称的虚拟主机配置添加到你的 Apache 配置文件中,就是这样,重新启动 Apache 并且你的测试域应该可以工作。

使用 mod_rewrite 重定向

如果您想使用 mod_rewrite 进行重定向(这样 user.example.com 不会直接托管,而是重定向到 example.com/user),那么您还需要执行 RewriteCond 以匹配子域并重定向它:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain\.example\.com
RewriteRule ^(.*)$ http://example.com/subdomain$1 [R]

你可以把它放在一个 .htaccess 或者你的主要 Apache 配置中。

您需要为要重定向的每个子域添加一对规则,例如最后两个规则。或者,您可以在 RewriteCond 中捕获子域,以便能够使用一个通配符规则将 *.example.com 重定向到 example.com/ * - 但从安全角度来看,这对我来说真的很糟糕。

一起,虚拟主机和重定向

最好更明确一点,为您要侦听的每个主机名设置一个虚拟主机配置部分,并将这些主机名中的每一个的重写规则放在其虚拟主机配置中。(如果可以的话,将这种东西放在 Apache 配置中而不是 .htaccess 中总是更安全、更快——.htaccess 会降低性能,因为 Apache 会不断地在文件系统中搜索 .htaccess 文件并重新解析它们,并且它不太安全,因为这些可能会被用户搞砸。)

这样一来,Apache 配置中的虚拟主机配置将是:

NameVirtualHost 127.0.0.1:80

# Your "default" configuration must go first
<VirtualHost 127.0.0.1:80>
  ServerName example.com
  ServerAlias www.example.com
  DocumentRoot /www/siteroot
  # etc.
</VirtualHost>

# First subdomain you want to redirect
<VirtualHost 127.0.0.1:80>
  ServerName vhost1.example.com
  RewriteEngine On
  RewriteRule ^(.*)$ http://example.com/vhost1$1 [R]
</VirtualHost>

# Second subdomain you want to redirect
<VirtualHost 127.0.0.1:80>
  ServerName vhost2.example.com
  RewriteEngine On
  RewriteRule ^(.*)$ http://example.com/vhost2$1 [R]
</VirtualHost>
于 2008-09-17T04:54:05.687 回答
7

我意识到我回答这个问题已经很晚了,但是在本地开发解决方案方面我遇到了同样的问题。在另一个 SO 线程中,我找到了更好的解决方案,并认为我会与将来有相同问题的任何人分享它们:

VMware 拥有的通配符域,可将任何子域解析为 127.0.0.1:

vcap.me resolves to 127.0.0.1
www.vcap.me resolves to 127.0.0.1

或更多功能 37 Signals 拥有一个域,可以使用特定格式将任何子域映射到任何给定 IP:

127.0.0.1.xip.io resolves to 127.0.0.1
www.127.0.0.1.xip.io resolves to 127.0.0.1
db.192.168.0.1.xip.io resolves to 192.168.0.1

有关更多信息,请参见xip.io

于 2012-11-26T20:03:22.060 回答
4

我在 Ubuntu 16.04 上,从 14.04 开始,我在这里使用 Dave Evans 提供的解决方案,它对我来说很好用。

  1. 安装dnsmasq

    sudo apt-get install dnsmasq
    
  2. 使用以下行在 dirlocalhost.conf下创建新文件/etc/dnsmasq.d

    #file /etc/dnsmasq.d/localhost.conf
    address=/localhost/127.0.0.1
    
  3. 编辑/etc/dhcp/dhclient.conf并添加以下行

    prepend domain-name-servers 127.0.0.1;
    

    (您可能会发现该行已经存在,您只需取消注释即可。)

  4. 最后一个是重启服务

    sudo systemctl restart dnsmasq
    sudo dhclient
    

最后,您应该检查它是否正常工作。

dig whatever.localhost

笔记:

如果您想在您的网络服务器上使用它,您只需将其更改127.0.0.0为您的实际 IP 地址。

于 2016-12-03T09:15:11.367 回答
1

我必须对我的一个网站做同样的事情。您可以按照以下步骤

  1. 如果您的服务器上有 cPanel,请创建子域*,如果没有,则必须在 DNS 中设置 A 记录(对于 BIND,请参见http://ma.tt/2003/10/wildcard-dns-和子域/)。在你的开发上。服务器您最好通过将每个子域添加到您的hosts文件来伪造子域。

  2. (如果您使用 cPanel,则不必这样做)。您必须将以下内容添加到您的 apache vhosts 文件中。这在很大程度上取决于您正在运行的服务器类型(共享与否)。以下代码不完整。它只是给方向。注意:ServerAlias example.com *.example.com很重要。

    <VirtualHost 127.0.0.1:80>  
            DocumentRoot /var/www/  
            ServerName example.com  
            ServerAlias example.com *.example.com  
    </VirtualHost>
    
  3. 接下来,因为您可以使用 PHP 脚本检查“主机”标头并找出子域并相应地提供内容。

于 2010-08-01T07:27:45.510 回答
0

首先,我想允许用户发布页面并给他们每个他们选择的子域(例如:user.mysite.com)。据我所知,最好的方法是使用 mod_rewrite 和 .htaccess 将 user.mysite.com 映射到 mysite.com/user - 对吗?

使用虚拟主机可能会更好。这样,每个用户都可以拥有一个几乎独立于其他用户的网络服务器配置。

语法是这样的:

<虚拟主机 *:80>
    DocumentRoot /var/www/user
    服务器名称 user.mysite.com
    ...
</虚拟主机>
于 2008-09-17T03:54:31.633 回答
0

从我在许多虚拟主机上看到的情况来看,他们在 apache 上设置了一个虚拟主机。

因此,如果您的 www.mysite.com 是从 /var/www 提供的,您可以为每个用户创建一个文件夹。然后将虚拟主机映射到该文件夹​​。

这样,mysite.com/user 和 user.mysite.com 都可以工作。

至于您的测试环境,如果您在 Windows 上,我建议编辑您的 HOSTS 文件以将 mysite.com 映射到您的本地 PC (127.0.0.1),以及您为测试设置的任何子域。

于 2008-09-17T04:09:33.593 回答
0

我为 Ubuntu 18.04 找到的解决方案与类似,但涉及 NetworkManager 配置:

  1. 编辑该文件/etc/NetworkManager/NetworkManager.conf,并将该行添加dns=dnsmasq到该[main]部分

    sudo editor /etc/NetworkManager/NetworkManager.conf
    

    应该是这样的:

    [main]
    plugins=ifupdown,keyfile
    dns=dnsmasq
    ...
    
  2. 开始使用 NetworkManager 的 resolv.conf

    sudo rm /etc/resolv.conf
    sudo ln -s /var/run/NetworkManager/resolv.conf /etc/resolv.conf
    
  3. 使用通配符配置创建文件

    echo 'address=/.localhost/127.0.0.1' | sudo tee /etc/NetworkManager/dnsmasq.d/localhost-wildcard.conf
    
  4. 重新加载 NetworkManager 配置

    sudo systemctl reload NetworkManager
    
  5. 测试一下

    dig localdomain.localhost
    

您还可以添加任何其他域,这对于使用本地开发设置时的某些类型的身份验证非常有用。

echo 'address=/.local-dev.workdomain.com/127.0.0.1' | sudo tee /etc/NetworkManager/dnsmasq.d/workdomain-wildcard.conf

然后这个工作:

dig petproject.local-dev.workdomain.com

;; ANSWER SECTION:
petproject.local-dev.workdomain.com. 0 IN   A   127.0.0.1
于 2018-08-21T13:02:17.827 回答