DedeCMS 本身并不直接支持二级域名,但我们可以利用其强大的标签和目录结构,通过 Web 服务器(如 Apache 或 Nginx)的配置来实现,核心思想是:将不同的二级域名指向网站根目录下的不同文件夹,然后使用 DedeCMS 的 {dede:global.cfg_basehost/} 标签来动态获取并拼接正确的域名。

下面我将分别以 Nginx 和 Apache 为例,提供详细的步骤。
核心原理
-
目录结构:在网站根目录下,为每个二级域名创建一个对应的文件夹。
- 网站根目录:
/www/wwwroot/yourdomain.com/ news.yourdomain.com对应文件夹:/www/wwwroot/yourdomain.com/news/blog.yourdomain.com对应文件夹:/www/wwwroot/yourdomain.com/blog/- 主站
www.yourdomain.com对应文件夹:/www/wwwroot/yourdomain.com/
- 网站根目录:
-
服务器配置:配置 Web 服务器,将所有
*.yourdomain.com的请求都指向网站根目录/www/wwwroot/yourdomain.com/。 -
DedeCMS 动态拼接:在 DedeCMS 的模板文件中,修改链接生成方式,使其能自动拼接上当前二级域名的目录名。
(图片来源网络,侵删)- 在
news目录下的文章,其链接应该是news.yourdomain.com/news/...而不是yourdomain.com/news/...。
- 在
第一步:准备工作
- 拥有一个顶级域名:
yourdomain.com。 - 域名解析:在你的域名解析服务商(如阿里云、腾讯云等)添加一个 (泛域名) 解析,指向你的服务器 IP 地址。
- 记录类型:
A - 主机记录:
- 记录值:你的服务器 IP 地址
- 记录类型:
- 服务器环境:确保你的服务器已安装 Nginx 或 Apache,并且已经成功运行 DedeCMS 5.7。
第二步:网站目录结构
假设你的 DedeCMS 安装在 /www/wwwroot/yourdomain.com/,目录结构如下:
/www/wwwroot/yourdomain.com/
├── /news/ (用于 news.yourdomain.com)
│ ├── dede/ (后台管理文件夹)
│ ├── templets/ (模板文件夹)
│ ├── special/ (专题文件夹)
│ ├── uploads/ (附件上传文件夹)
│ ├── index.php (入口文件)
│ ├── data/ (数据缓存文件夹)
│ └── ... (其他 dedecms 文件)
├── /blog/ (用于 blog.yourdomain.com)
│ ├── dede/
│ ├── templets/
│ ├── ...
│ └── index.php
├── /dede/ (主站后台管理)
├── /templets/ (主站模板)
├── /special/
├── /uploads/
├── index.php (主站入口文件)
├── data/
└── ... (其他 dedecms 文件)
操作:复制一份 DedeCMS 的完整安装包到 news 和 blog 目录中,注意,只需要复制程序文件,不需要复制数据库文件。
第三步:服务器配置
Nginx 配置 (推荐)
Nginx 的配置更简洁高效,是目前的主流选择。
-
打开你的 Nginx 配置文件,通常位于
/usr/local/nginx/conf/nginx.conf或在/etc/nginx/sites-available/下的站点配置文件中。
(图片来源网络,侵删) -
在
server块中添加以下配置:
# 将所有二级域名请求指向网站根目录
server {
listen 80;
server_name *.yourdomain.com; # 匹配所有二级域名
root /www/wwwroot/yourdomain.com; # 网站根目录
index index.php index.html index.htm;
# ... 其他配置,如伪静态规则等 ...
# 关键部分:将请求重写到对应的目录
if ($http_host ~* ^(.+)\.yourdomain\.com$) {
set $subdomain $1;
if ($subdomain != "www") {
# 如果是 www,则不重定向,访问主站
# 如果不是 www,则重定向到 /$subdomain/ 目录
rewrite ^/(.*)$ /$subdomain/$1 last;
}
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; # 或 unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# ... 其他 location 配置 ...
}
配置解释:
server_name *.yourdomain.com;:监听所有以yourdomain.com结尾的二级域名。root /www/wwwroot/yourdomain.com;:设置网站根目录。if ($http_host ~* ...):这是一个正则匹配,检查请求的域名。set $subdomain $1;:将匹配到的子域名部分(如news)存入变量$subdomain。rewrite ^/(.*)$ /$subdomain/$1 last;:这是核心重写规则,它将所有请求路径前加上$subdomain变量的值,访问news.yourdomain.com/a/b.html会被重写为/www/wwwroot/yourdomain.com/news/a/b.html。
- 保存配置文件,然后重启 Nginx 服务:
nginx -t && nginx -s reload
Apache 配置
如果你的服务器使用 Apache,请进行如下配置。
-
确保你的 Apache 已经开启了
mod_rewrite模块。 -
打开你的虚拟主机配置文件(通常在
/etc/apache2/sites-enabled/000-default.conf或/etc/httpd/conf/httpd.conf)。 -
在
<VirtualHost>块中添加以下配置:
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com *.yourdomain.com # 添加泛域名别名
DocumentRoot /www/wwwroot/yourdomain.com
# ... 其他配置 ...
# 关键部分:使用 mod_rewrite 进行重定向
<IfModule mod_rewrite.c>
RewriteEngine On
# 如果不是 www.yourdomain.com,则进行重写
RewriteCond %{HTTP_HOST} !^www\.yourdomain\.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.yourdomain\.com [NC]
RewriteRule ^(.*)$ /%1/$1 [L]
</IfModule>
# ... 其他配置,如处理 .php 的部分 ...
</VirtualHost>
配置解释:
ServerAlias *.yourdomain.com:声明所有二级域名都由这个虚拟主机处理。RewriteEngine On:开启重写引擎。RewriteCond:重写条件。- 第一个条件:确保主机名不是
www.yourdomain.com,避免主站被重定向。 - 第二个条件:将主机名
news.yourdomain.com中的news捕获到%1中。
- 第一个条件:确保主机名不是
RewriteRule ^(.*)$ /%1/$1 [L]:重写规则,将所有请求路径前加上捕获到的子域名%1。
- 保存配置文件,然后重启 Apache 服务:
systemctl restart apache2
第四步:修改 DedeCMS 模板(最关键的一步)
无论用户访问 news.yourdomain.com 还是 blog.yourdomain.com,服务器都会将他们引导到正确的文件夹,DedeCMS 默认生成的链接仍然是基于主域名的,在 news 目录下生成的文章链接是 yourdomain.com/news/...,而不是 news.yourdomain.com/news/...。
我们需要修改 DedeCMS 的核心标签来解决这个问题。
核心思路:获取当前请求的目录名,然后动态拼接到 {dede:global.cfg_basehost/} 后面。
修改 include/typelink.class.php 文件(推荐,一劳永逸)
这个文件负责生成所有类型的链接,修改它可以确保所有类型的链接(列表页、文章页、首页等)都正确。
-
打开
/include/typelink.class.php文件。 -
找到
GetLinkTypeUrl()函数(通常在第 100 行左右)。 -
将原来的代码:
// ... if($type=='') { $type = 'index'; } $url = $this->indexGetUrl($type); // ...修改为:
// ... if($type=='') { $type = 'index'; } // --- 新增代码开始 --- // 获取当前请求的目录名 $current_dir = trim(dirname($_SERVER['PHP_SELF']), '/'); if ($current_dir != '' && $current_dir != 'yourdomain.com') { // 'yourdomain.com' 是你的顶级域名 // 获取当前域名 $host = $_SERVER['HTTP_HOST']; // 拼接新的URL $url = 'http://' . $host . '/' . $current_dir . '/' . $this->indexGetUrl($type, false); } else { // 如果在根目录,则使用原来的逻辑 $url = $this->indexGetUrl($type); } // --- 新增代码结束 --- // ...注意:
$this->indexGetUrl($type, false)中的false参数是为了防止函数内部再次拼接$GLOBALS['cfg_basehost'],因为我们已经手动拼接了。
修改 templets/ 目录下的模板文件(备用方案)
如果不想修改核心文件,也可以直接修改模板文件,这种方法更直观,但需要为每个模板都进行修改。
-
修改首页链接 (
index.htm): 将<a href="{dede:global.cfg_basehost/}/">修改为<a href="//{dede:global.cfg_basehost/}/">,使用 是一种相对协议的写法,会自动继承当前页面的协议(http 或 https)。 -
修改文章/列表页链接: 将类似
<a href="[field:arcurl/]">的标签修改为使用绝对路径。<!-- 修改前 --> <a href="[field:arcurl/]">[field:title/]</a> <!-- 修改后 --> <a href="http://{dede:global.cfg_basehost/}/[field:typedir/]/[field:id].html">[field:title/]</a>这种方法比较繁琐,不推荐,因为失去了 DedeCMS 标签的灵活性。强烈推荐第一种修改
typelink.class.php的方法。
第五步:测试
完成以上所有步骤后,进行测试:
- 清理浏览器缓存。
- 访问
news.yourdomain.com,检查是否正确显示了news目录下的首页内容。 - 在
news首页点击任意一篇文章,检查文章的 URL 是否为http://news.yourdomain.com/news/...的格式。 - 访问
blog.yourdomain.com,重复上述测试。 - 访问
www.yourdomain.com,确保主站不受影响,仍然正常工作。
常见问题与注意事项
- 后台登录:每个二级域名目录下都有一个独立的
/dede/后台。news.yourdomain.com/dede/。 - 数据共享:默认情况下,所有二级域名目录都共享同一个数据库,这意味着
news和blog的文章、分类等数据都在同一个库里,如果你希望它们完全独立,需要为每个二级域名安装一套独立的 DedeCMS,并使用不同的数据库前缀。 - 图片和附件路径:由于我们修改了链接生成逻辑,附件和图片的路径也应该能正确生成了,如果仍有问题,可以检查后台的“系统” -> “基本参数” -> “核心设置”中的“附件目录是否使用绝对路径”选项。
- 伪静态规则:为每个二级域名目录(如
/news/)配置独立的伪静态规则,或者确保根目录的伪静态规则能正确应用到子目录中。 - SSL/HTTPS:如果网站启用了 HTTPS,需要确保你的 SSL 证书支持泛域名(通配符证书),并且服务器配置中也要监听
443端口,配置方式与80端口类似。
通过以上步骤,你就可以成功地在 DedeCMS 5.7 上实现功能完善的二级域名了。
