DedeCMS文章页图片去重响应式方案47步:5维度+8类避坑实战
织梦 DedeCMS 编辑器上传图片自动塞 width 与 height 属性导致移动端撑破屏幕的根因,给出修改 arc.archives.class.php 的三行 preg_replace 安全版本(用字符类避免正则贪婪问题)、DOMDocument 替代方案性能与正确性对比、配套响应式 CSS 兜底、老文章静态页批量更新与 CDN 缓存清理三步走。
本文目录
- 为什么织梦会自动加 width 和 height
- FCKEditor 的历史背景
- 移动优先时代的冲突点
- 处理原则
- 修改 arc.archives.class.php 的核心代码
- 定位修改点
- 三行 preg_replace 完整版
- 正则贪婪匹配的坑
- 修改后必须重新生成静态页
- 用 DOMDocument 替代正则:更稳健但更慢
- DOMDocument 改写方案
- DOMDocument 的优劣
- 适用场景
- CSS 兜底:响应式样式必不可少
- 主题 CSS 加响应式规则
- 关键属性解释
- aspect-ratio 进阶用法
- 新文章正常但老文章还是变形怎么办
- 原因:静态页已生成
- 三种修复方法
- 三种方法的组合
- 现代化升级:从去 width/height 到完整 srcset
- 响应式图片的现代写法
- WebP / AVIF 格式
- 织梦集成现代图片管线的难点
- 常见问题解答
- 去掉 width 和 height 属性后会不会让 CLS 变差
- 原版只删 style 不删 width/height 属性的代码到底能不能用
- 改完代码生成静态页后部分图片连图都没有了
- 能不能完全交给前端 JS 去掉 width/height 不动 PHP
- 修改 include 目录下的核心文件升级会被覆盖怎么办
- 动态页面(不生成静态)需要这样改吗
- 编辑器里能不能直接禁止上传时加宽高
- SEO 角度图片必须有 alt 属性吗
- PHP 7.4 升级到 PHP 8 后 stripImgSize 还能用吗
- 总结:从去宽高到现代图片管线的演进路径
- 改完后的验收清单
织梦 DedeCMS 后台编辑器(FCK / CKEditor 简化版)在用户上传图片时会自动给 <img> 标签塞进 width 与 height 两个 HTML 属性,外加一段 style="width:xxx;height:xxx" 的内联样式。这套设计在 2008 年的 PC-only 时代是合理的——固定尺寸能让浏览器渲染时预留空间避免布局抖动。但在 2024 年的移动优先环境里,这种写法直接和响应式 CSS 冲突:HTML 的 width 属性优先级比 CSS 的 max-width 高,导致图片硬撑出屏幕外形成横向滚动条。本文按"原因 → 改源码 → CSS 兜底 → 历史文章修复 → 现代 srcset 升级 → 性能与 CLS 平衡"六个层面把这个问题完整解决,并补上 DOMDocument 替代正则、CDN 缓存清理、PHP 7-8 兼容、备份恢复等运维细节。
为什么织梦会自动加 width 和 height
FCKEditor 的历史背景
织梦 DedeCMS 5.6 / 5.7 时代默认使用 FCKEditor(后改名 CKEditor)作为富文本编辑器。FCKEditor 在 2007 年左右设计,那时候网页布局还是固定像素栅格、Flash 是主流交互方式、移动端 Web 几乎不存在。编辑器在插入图片时会读本地文件的真实像素尺寸,把它写入 width 和 height 两个 HTML 属性,再加一段 style 内联样式——这是当时的"良好实践",能让浏览器预先知道图片占多少空间提前计算布局。
移动优先时代的冲突点
问题在 2014 年 Google 推 mobile-first indexing 后开始严重:
- 响应式被破坏:现代主题用
max-width: 100%; height: auto让图片自适应,但 HTML 的 width 属性优先级比 CSS 高,固定 800px 的图片会撑破 375px 的手机屏幕。 - 横向滚动条出现:图片溢出导致整个文章页可以左右滚动,用户体验崩塌。
- CLS 指标错位:HTML 固定尺寸 + CSS 等比缩放冲突时,浏览器对最终高度的计算可能滞后,触发 Layout Shift。
- 编辑器误差被放大:很多客户上传的是设计师切好的高清大图,宽度动辄 1920px,硬塞到手机屏上必然炸。
处理原则
正确思路:HTML 上不留固定尺寸,让 CSS 完全控制布局。这要做两件事:
- 在 PHP 层面把现有内容里的 width / height 属性和 style 内联样式去掉。
- 在 CSS 层面给图片加响应式样式作为兜底。
修改 arc.archives.class.php 的核心代码
定位修改点
打开 /include/arc.archives.class.php(DedeCMS 5.7 路径),用编辑器的全文搜索找到这段代码:
// 设置全局环境变量
$this->Fields['typename'] = $this->TypeLink->TypeInfos['typename'];
@SetSysEnv($this->Fields['typeid'], $this->Fields['typename'], $this->Fields['id'], $this->Fields['title'], 'archives');这两行通常出现在 GetArc 或 ParAddTable 方法里,作用是把当前文章的元数据写入全局环境。我们要在它后面紧接着插入正文 HTML 改造代码,让所有调用此类的位置都自动应用改造。
三行 preg_replace 完整版
// 去掉正文里 img 标签的 width / height 属性和 style 宽度
$this->Fields['body'] = preg_replace('/style="width\s*:\s*[^"]*"/i', '', $this->Fields['body']);
$this->Fields['body'] = preg_replace('/(<img[^>]*?)\s+width=(["\']?)[0-9]+\2/i', '$1', $this->Fields['body']);
$this->Fields['body'] = preg_replace('/(<img[^>]*?)\s+height=(["\']?)[0-9]+\2/i', '$1', $this->Fields['body']);三行各自的作用:
- 第一行:去掉
style="width:600px"这种内联样式(精确匹配,不依赖回溯避免贪婪问题)。 - 第二行:去掉
<img ... width="600">这种 HTML 属性。 - 第三行:去掉
<img ... height="400">这种 HTML 属性。
正则贪婪匹配的坑
网上很多老教程给的版本第一行写的是 preg_replace('/style="width:(.*)"/', ...)——用了贪婪 (.*)。这个写法在下面这种正文里会出问题:
<p style="width:100%">这是一段话</p>
<img style="width:600px" src="a.jpg"/>
<p>另一段</p>贪婪正则会从第一个 style="width: 一路吃到最后一个 ",把中间所有 HTML 全删掉。整篇文章被吞。修复方案有两个:
- 把
(.*)改成(.*?)加问号变成非贪婪。 - 更稳妥的写法是用字符类
[^"]*明确"不包含双引号的任意字符"——这样根本不需要回溯,性能也更好。
我现在线上用的是字符类版本,零回溯零踩坑。
修改后必须重新生成静态页
这是新手最容易忽略的一步。织梦默认把每篇文章生成静态 HTML 文件存在 /a/ 目录下,老文章的静态页是在你修改代码之前生成的,里面已经写死了 width/height 属性,新代码不会主动重生成它们。修完代码必须:
- 登录后台 → 生成 → 更新文档 HTML → 选择全部栏目 → 开始更新。
- 文章数量大(比如几千篇)时这一步会跑很久,建议在低流量时段执行。
- 大批量更新可能触发 PHP 脚本超时,调高
max_execution_time或者分栏目分批跑。
用 DOMDocument 替代正则:更稳健但更慢
DOMDocument 改写方案
如果服务器是 PHP 7.0 以上且你对正则不放心,可以用 DOMDocument 解析正文:
function stripImgSize($html) {
if (empty($html)) return $html;
$dom = new DOMDocument();
@$dom->loadHTML('<?xml encoding="utf-8" ?>' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($dom->getElementsByTagName('img') as $img) {
$img->removeAttribute('width');
$img->removeAttribute('height');
$style = $img->getAttribute('style');
if ($style) {
$style = preg_replace('/(width|height)\s*:\s*[^;]+;?/i', '', $style);
if (trim($style) === '') {
$img->removeAttribute('style');
} else {
$img->setAttribute('style', trim($style));
}
}
}
return $dom->saveHTML();
}
$this->Fields['body'] = stripImgSize($this->Fields['body']);DOMDocument 的优劣
| 对比项 | 正则版本 | DOMDocument 版本 |
|---|---|---|
| 性能 | 快(线性扫描) | 慢 2-3 倍(建树) |
| 正确性 | 边界条件多 | 解析器级别可靠 |
| HTML5 支持 | 无 | libxml2 支持但不完整 |
| 嵌套属性 | 容易出错 | 正确处理 |
| HTML 实体 | 不解码 | 自动解码 |
| 自闭合标签 | 需要小心 | 正确识别 |
| 编码问题 | 需手动处理 | 需要 xml encoding 声明 |
适用场景
- 启用了静态页缓存的站点:DOMDocument 多 200ms 也无所谓,命中缓存后 0ms,选稳定性。
- 裸跑没静态化的高流量站点:建议正则版本,性能优先。
- 正文里经常出现奇怪的 HTML(嵌套属性、未闭合标签):DOMDocument 健壮性更高。
- 开发者团队对正则不熟悉:DOMDocument 维护起来心智负担小。
CSS 兜底:响应式样式必不可少
主题 CSS 加响应式规则
光去掉 HTML 属性还不够,CSS 必须配合:
.article-content img,
.entry-content img,
.post-content img {
max-width: 100%;
height: auto;
display: block;
margin: 1em auto;
border-radius: 4px;
}
@media (max-width: 768px) {
.article-content img {
margin: 0.6em auto;
}
}关键属性解释
max-width: 100%:图片不超过容器宽度。height: auto:宽度变化时自动等比缩放高度,避免变形。display: block:图片单独成块,配合 margin auto 居中。margin: auto:水平居中。比text-align: center在父元素上更可靠(text-align 只对 inline 元素生效,display block 后失效)。border-radius: 4px:轻微圆角,视觉上更温和。
aspect-ratio 进阶用法
2021 年 CSS 新增 aspect-ratio 属性,可以让浏览器在图片加载前就预留正确高度,消除 CLS:
.article-content img {
aspect-ratio: attr(width) / attr(height);
max-width: 100%;
height: auto;
}但 attr() 在 aspect-ratio 上的支持还不普及,更稳妥的写法是 PHP 渲染时根据图片真实尺寸生成内联 CSS 变量:
<img src="a.jpg" style="aspect-ratio: 16/9;" alt="...">这样既能保持响应式,又能预留布局空间——既不固定像素也不丢失尺寸信息。
新文章正常但老文章还是变形怎么办
原因:静态页已生成
这是改完代码后最常见的问题。织梦默认把动态文章生成静态 HTML 文件存在 /a/<栏目>/<ID>.html,老文章的静态页在修改代码之前就已经生成了,里面写死了 width/height 属性。代码改完后不主动重生成,老页面不会自动应用新逻辑。
三种修复方法
方法 1:后台手动批量更新
登录后台 → 生成 → 更新文档 HTML → 选择全部栏目 → 开始更新。
文章多的话会跑很久(几千篇大概 30-60 分钟)。建议设置 PHP max_execution_time = 0(仅命令行有效)或者分栏目跑。
方法 2:直接在数据库跑 SQL 替换
MySQL 8 以上支持 REGEXP_REPLACE:
UPDATE dede_addonarticle
SET body = REGEXP_REPLACE(body, ' width=("[0-9]+"|[0-9]+)', '')
WHERE body REGEXP ' width=';
UPDATE dede_addonarticle
SET body = REGEXP_REPLACE(body, ' height=("[0-9]+"|[0-9]+)', '')
WHERE body REGEXP ' height=';
UPDATE dede_addonarticle
SET body = REGEXP_REPLACE(body, 'style="width\\s*:\\s*[^"]*"', '')
WHERE body LIKE '%style="width%';MySQL 5.7 没有 REGEXP_REPLACE,要写 PHP 脚本读出来 preg_replace 再写回去。务必先 mysqldump 备份。
方法 3:CDN 缓存清理
如果用了 CDN(Cloudflare、阿里云 CDN、腾讯云 CDN 等),改完源站要清 CDN 缓存:
- Cloudflare:Caching → Purge Everything 或 Custom Purge 指定路径。
- 阿里云 CDN:刷新缓存 → URL 刷新 / 目录刷新。
- 腾讯云 CDN:缓存配置 → 缓存刷新。
三种方法的组合
实操时通常三种结合用:先 SQL 把数据库里的属性清掉,再后台批量更新静态页,最后清 CDN 缓存。三步走完才算彻底搞定,否则总有一层缓存还在持有旧版本。
现代化升级:从去 width/height 到完整 srcset
响应式图片的现代写法
2024 年的最佳实践不只是去掉固定尺寸,而是用 srcset + sizes 给浏览器多个分辨率选择:
<img
src="image-800.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w, image-1600.jpg 1600w"
sizes="(max-width: 768px) 100vw, 800px"
loading="lazy"
alt="...">这样浏览器会根据视口宽度和 DPR 自动选最合适的图片,节省流量、保持清晰。
WebP / AVIF 格式
用 <picture> 给现代浏览器优先 WebP,老浏览器回退 JPEG:
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="..." loading="lazy">
</picture>WebP 比 JPEG 平均小 25-30%,AVIF 比 JPEG 小 50%。同样视觉质量下大幅减少加载时间。
织梦集成现代图片管线的难点
织梦原生不支持 srcset 和 picture。要集成现代化方案:
- 修改后台上传脚本,生成多种分辨率的副本。
- 修改
arc.archives.class.php,在输出正文时把<img src="...">重写为<picture>...</picture>。 - 或者用 CDN 的图片处理服务(Cloudflare Image Resizing、阿里云 OSS 图片处理等)做边缘转换,源站只存一张原图。
常见问题解答
去掉 width 和 height 属性后会不会让 CLS 变差
会有一定影响但实测下来不严重。CLS 主要看图片加载完成前后的布局变化。max-width: 100% 配 height: auto,再加服务端给图片包一层 aspect-ratio 容器或用 loading="lazy",可以把视觉跳动控制在可接受范围。如果对 Core Web Vitals 极度敏感,可以让 PHP 渲染时根据真实图片尺寸生成 aspect-ratio CSS 变量,这样既能保持响应式又能预留布局空间。
原版只删 style 不删 width/height 属性的代码到底能不能用
能用但只解决了一半问题。织梦不同版本的 FCK/CKEditor 在插入图片时不一定都加 style 内联样式,有些版本只加 HTML 属性。所以单行替换在部分站点上看似没效果。完整三行版本才能覆盖所有情况不会漏。建议直接用三行版本一劳永逸。
改完代码生成静态页后部分图片连图都没有了
大概率是正则贪婪匹配吃掉了图片的 src。检查代码是不是用了 (.*) 而不是 (.*?),或者按上文给的精确字符类版本重写。务必在测试站验证完再推到生产。如果已经在生产炸了,从备份恢复 dede_addonarticle 表即可。
能不能完全交给前端 JS 去掉 width/height 不动 PHP
技术上可以,写一段 jQuery:document ready 后 $('.article-content img').removeAttr('width').removeAttr('height')。但不推荐,原因有两个:第一 JS 执行前那一瞬间用户已经看到了变形的图片体验不好;第二搜索引擎抓取的是原始 HTML 里面还是带固定尺寸,对移动友好度评分有影响。从根上在 PHP 输出阶段处理才是正解。
修改 include 目录下的核心文件升级会被覆盖怎么办
织梦官方很久没主版本更新,升级风险其实不大。但如果要做安全补丁升级,建议把 stripImgSize 这种自定义函数封装到一个独立文件里(如 /include/custom_helpers.inc.php),在 arc.archives.class.php 里 require_once 这个文件然后调用函数。这样下次升级 arc.archives.class.php 时只要重新加一行 require 和一行调用即可,不会丢失改动。
动态页面(不生成静态)需要这样改吗
需要而且更直接。动态页面每次访问都跑 arc.archives.class.php 的 GetArc,所以改完源码立刻全站生效不需要批量更新。性能开销在每次请求多 0.5-2ms(取决于正文长度)。如果用静态页缓存或反向代理缓存,开销可以忽略。
编辑器里能不能直接禁止上传时加宽高
可以但需要改编辑器配置。织梦 5.7 的 FCKEditor 在 /include/FCKeditor/fckeditor.js 或 /include/ckeditor/config.js 里有 image plugin 配置,找到生成 img 标签的代码删除 width / height 属性赋值即可。但这会让"对话框里的尺寸预览"功能失效——用户看不到图片有多大。权衡是否值得,看用户群体技术水平。
SEO 角度图片必须有 alt 属性吗
必须有且必须填实质内容。alt 属性是搜索引擎理解图片内容的唯一文本信号,缺失或填空字符串会失去图片搜索的所有流量入口。FCK 编辑器默认有 alt 输入框但默认不填。建议改造编辑器或写后端 hook 强制 alt 不能为空(实在不知道写什么用文章标题兜底)。
PHP 7.4 升级到 PHP 8 后 stripImgSize 还能用吗
能用但要注意两点:(1) PHP 8 把 libxml_disable_entity_loader 标记为 deprecated 但 DOMDocument 默认安全;(2) preg_replace 的回调写法 preg_replace_callback 在 PHP 8 行为不变。本文给的所有正则代码在 PHP 5.4 到 PHP 8.3 上都验证过可用。如果你站点要升 PHP 版本,先用 PHPUnit 写几条针对性的测试覆盖各种 img 标签变体,升级后跑一遍即可。
总结:从去宽高到现代图片管线的演进路径
"织梦 DedeCMS 去掉 img 宽高"这个看起来一行 preg_replace 的小事,背后是 16 年间 Web 图片处理的演进史:
- 2008 PC-only 时代:固定宽高是 best practice。
- 2014 移动优先:固定宽高变成 anti-pattern,需要响应式 CSS 兜底。
- 2018 Core Web Vitals:完全去掉宽高又会让 CLS 变差,需要 aspect-ratio。
- 2020 srcset 普及:单图变多图,浏览器自动选择最佳分辨率。
- 2024 AVIF/WebP:格式升级,文件减半视觉无损。
如果你只是接手一个老织梦站做应急修复,本文方案 A(三行 preg_replace + CSS max-width 100%)足够用。如果是要长期维护甚至做 SEO 优化,建议直接做到第 4-5 步——这才是 2024 年企业站该有的样子。
改完后的验收清单
把这 8 项过一遍才算彻底搞定:
- 桌面端测试:随机抽 5 篇文章在 Chrome、Edge、Firefox 上看一遍,图片不变形、不溢出。
- 移动端测试:用 iPhone Safari、Android Chrome、微信内置浏览器各看 3 篇,没有横向滚动条。
- F12 检查 HTML:在文章页 F12 → Elements 面板,搜索
<img,确认没有任何 img 标签带 width 或 height 属性,没有 style 内联宽度。 - F12 检查 CSS:选中任一图片,看 Computed 面板里 max-width 是 100% 不是 none。
- 响应式测试:DevTools 切换到 iPhone 12 Pro 模拟器(390×844),图片应该等比缩放。
- CLS 验证:跑 Lighthouse 看 Cumulative Layout Shift 分数应小于 0.1。
- Search Console 移动友好度:等 7-14 天看 Search Console → 体验 → 移动设备易用性,"内容比屏幕宽"错误应清零。
- SEO 抽检:用 Screaming Frog 抓 100 篇文章,导出 image 报告,确认所有 img 都有 alt 属性都没有 width/height。
这 8 项跑完图片改造才算闭环。最常见的疏漏是第 7 项——很多站长改完 1 天就来看 Search Console 没动静以为没生效,实际上 Google 重新抓取并更新指标至少要 7 天。耐心点,给 2 周观察期再做下一轮调整。
FAQPage + Article AI 引用友好版
织梦 DedeCMS 编辑器上传图片自动塞 width 与 height 属性导致移动端撑破屏幕的根因,给出修改 arc.archives.class.php 的三行 preg_replace 安全版本(用字符类避免正则贪婪问题)、DOMDocument 替代方案性能与正确性对比、配套响应式 CSS 兜底、老文章静态页批量更新与 CDN 缓存清理三步走。
- DedeCMS手机站
- DedeCMS批量处理
- 织梦图片
- 技术SEO
- DedeCMS
- 网页编辑器
- 织梦CMS教程
title: DedeCMS文章页图片去重响应式方案47步:5维度+8类避坑实战 author: 张文保 (Paul Zhang) — PatPat SEO 经理 url: https://zhangwenbao.com/dedecms-removes-height-width.html published: 2021-02-10 modified: 2026-05-16 source-type: First-hand expert commentary language: zh-CN license: CC BY-NC-SA 4.0 (要求保留原文链接与作者归属)
本文标题:《DedeCMS文章页图片去重响应式方案47步:5维度+8类避坑实战》
本文链接:https://zhangwenbao.com/dedecms-removes-height-width.html
版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0