在商品编辑页选择图片后立即能看到预览,但点击保存再打开商品,图片不见了。预览成功只证明浏览器把文件上传到临时位置,不代表 Magento 已把它移动到正式媒体目录并写入商品 Media Gallery。

观察临时上传与商品保存两个请求

Network 中先找到图片上传请求,再看商品保存请求。上传接口返回的临时文件名、cookie 和 form key 必须被保存表单带回。保存返回 200 但响应体是错误页、Session 过期或部分字段被截断时,图片元数据可能没进入后端。

检查 tmp 与正式目录的文件流转

商品图片通常先进入临时目录,再在保存时移动到 pub/media/catalog/product。Web 用户需要读写相关目录。多节点后台若上传请求落在节点 A、保存请求落在节点 B,而 media/tmp 不共享,节点 B 找不到临时文件。

检查文件所有者、目录执行权限、共享存储与同步延迟,不要通过 777 长期解决。对象存储或远程媒体适配器还要检查 rename/copy 能力和失败日志。

数据库需要同时保存 Gallery 与角色属性

图片库记录和 image、small_image、thumbnail 角色不是同一份数据。可查询指定商品的 Gallery 关联:

SELECT mg.value_id, mg.value, mg.media_type,
       mgv.store_id, mgv.label, mgv.position, mgv.disabled
FROM catalog_product_entity_media_gallery mg
JOIN catalog_product_entity_media_gallery_value mgv
  ON mgv.value_id=mg.value_id
WHERE mgv.entity_id=123;

不同版本的关联表结构可能变化,先确认 schema。文件存在但没有 Gallery 记录,问题在保存;记录存在但 disabled 或 Store View 覆盖,也会在后台看似消失。

商店作用域与“Use Default Value”容易混淆

在某个 Store View 上传或删除图片时,值可能只对该视图生效。默认视图有图,子商店把 Gallery 禁用,前台仍不显示;反过来子视图上传后切回默认,也可能看不到。确认编辑器顶部的 scope 和角色覆盖状态。

图片验证和插件可能在保存阶段拒绝

文件扩展名、实际 MIME、尺寸、内存、特殊字符或损坏图片可能通过浏览器预览,却在后端处理时失败。安全模块和图片优化扩展也可能移动或删除文件。按保存时间查看 exception、system、PHP 与安全扫描日志。

修复后上传一张新图,设置三个角色、保存、刷新后台,并在另一个 Web 节点和前台访问。再删除和重新排序一次,确认文件、Gallery 数据、角色和 Store View 状态保持一致。