测试环境显示 1688 图片:`referrerpolicy: ‘no-referrer‘` 实践说明

测试环境显示 1688 图片:referrerpolicy: 'no-referrer' 实践说明

背景

业务页面经常需要展示来自阿里巴巴 / 1688 CDN 的商品图,典型域名包括:

  • cbu01.alicdn.com
  • global-img-cdn.1688.com

在线上(正式域名)访问时,这些图片通常可以正常加载。但在测试环境 (本地 localhost、内网测试域名、非白名单域名)里,同 URL 的图片经常会出现:

  • 裂图 / 空白
  • 控制台报 403 / 防盗链相关错误
  • Network 面板里请求被 CDN 拒绝

表面看像是「图片地址错了」,实际多数是 Referer 防盗链 拦截。

原因:CDN 会校验 Referer

浏览器请求外链图片时,默认会带上当前页面的 Referer(来源页地址)。例如:

当前页面 请求图片时带上的 Referer(示意)
https://product.xxx.com/... https://product.xxx.com/
http://localhost:3000/... http://localhost:3000/
https://test-xxx.company.com/... https://test-xxx.company.com/

1688 / 阿里 CDN 会对 Referer 做白名单校验:

  • 正式业务域名:通常在白名单内 → 图片可访问
  • 测试 / 本地域名:不在白名单 → CDN 拒绝返回图片

所以:同一张 1688 图片 URL,在正式环境能看、在测试环境不能看,往往不是业务代码拼错路径,而是 Referer 策略差异。

解决方案:不发送 Referer

HTML 图片标签支持 referrerpolicy。设置为 no-referrer 后,浏览器在请求该图片时不携带 Referer

对许多 CDN 而言:

  • 有非法 / 非白名单 Referer → 拒绝
  • 没有 Referer → 允许放行(或按宽松策略处理)

因此测试环境可通过「不传 Referer」绕过防盗链限制,从而正常显示 1688 图片。

说明:这是前端展示层的兼容手段,不改变图片 URL 本身,也不替代后端镜像 / 代理方案。

在 Naive UI n-image 中的用法

项目里使用 Naive UI 的 n-image。底层最终会渲染原生 <img>,可通过 :img-props 把属性透传给真实 img 节点。

示例(寻源关联抽屉 sourceModel.vue):

vue 复制代码
<n-image
  class="w-[70px] h-[70px] rounded-md"
  :img-props="{ referrerpolicy: 'no-referrer' }"
  :src="item?.includes('//cbu01.alicdn.com/') ? item : getPathImage(item, 120, 120)"
  :preview-src="item?.includes('//cbu01.alicdn.com/') ? item : getPathImage(item, 0, 0)"
/>

关键点:

ts 复制代码
:img-props="{ referrerpolicy: 'no-referrer' }"

n-image:img-props 最终会落到原生 <img> 上,效果与下一节的原生写法一致。

原生 <img> 中的用法

不依赖组件库时,直接在 <img> 上写 referrerpolicy="no-referrer" 即可。

HTML

html 复制代码
<img
  src="https://cbu01.alicdn.com/img/ibank/xxx.jpg"
  alt="1688商品图"
  referrerpolicy="no-referrer"
  width="120"
  height="120"
/>

Vue 模板

vue 复制代码
<img
  class="w-[70px] h-[70px] rounded-md"
  referrerpolicy="no-referrer"
  :src="item?.includes('//cbu01.alicdn.com/') ? item : getPathImage(item, 120, 120)"
  alt="商品图"
/>

属性也可以写成绑定形式(效果相同):

vue 复制代码
<img
  :referrerpolicy="'no-referrer'"
  :src="aliImageUrl"
  alt="商品图"
/>

动态创建 Image 对象

用 JS 预加载、导出画布、或自定义预览时,记得给 DOM/Image 实例设置 referrerPolicy(注意驼峰):

js 复制代码
const img = new Image()
img.referrerPolicy = 'no-referrer'
img.onload = () => {
  // 加载成功后再绘制 / 展示
}
img.src = 'https://cbu01.alicdn.com/img/ibank/xxx.jpg'

Vue 里通过 ref 操作原生节点时同理:

ts 复制代码
imgRef.value.referrerPolicy = 'no-referrer'
imgRef.value.src = aliUrl

n-image 与原生 <img> 对照

写法 如何设置
Naive UI n-image :img-props="{ referrerpolicy: 'no-referrer' }"
原生 <img> referrerpolicy="no-referrer"
new Image() img.referrerPolicy = 'no-referrer'(驼峰)

三者原理相同:让图片请求不携带 Referer,从而在测试环境通过 1688 CDN 防盗链校验。

和现有图片处理逻辑的配合

项目中站内图一般走 getPathImage 做裁剪 / WebP;1688 CDN 图通常原样使用,不走站内缩略图规则:

ts 复制代码
item?.includes('//cbu01.alicdn.com/')
  ? item
  : getPathImage(item, 120, 120)

建议约定:

  1. 1688 / 阿里 CDN 外链 :直接用原 URL + referrerpolicy: 'no-referrer'
  2. 站内 OSS / 自有 CDN :继续走 getPathImage
  3. srcpreview-src 保持同一套判断,避免缩略图与预览图策略不一致

如何验证

  1. 打开测试环境含 1688 图片的页面。
  2. DevTools → Network → 筛选图片请求。
  3. 查看 Request Headers:
    • 修复前 :通常带有 Referer: http://localhost:... 或测试域名
    • 修复后 :该图片请求没有 Referer(或策略符合 no-referrer
  4. 图片应可正常显示;若仍失败,再排查 URL 是否过期、是否需 https、是否被公司网络拦截。

也可在控制台快速对比:

js 复制代码
// 可能失败(带当前页 Referer)
const img1 = new Image()
img1.src = 'https://cbu01.alicdn.com/xxx.jpg'

// 更可能成功(不带 Referer)
const img2 = new Image()
img2.referrerPolicy = 'no-referrer'
img2.src = 'https://cbu01.alicdn.com/xxx.jpg'

适用场景与注意点

适合

  • 测试 / 本地调试需要看 1688 商品图
  • 前端直接用 n-image / <img> 展示外链
  • 临时兼容防盗链,快速恢复联调体验

注意

  1. 不是万能钥匙

    若 CDN 强制要求合法 Token、Cookie、签名 URL,仅去掉 Referer 仍可能失败。

  2. 预览层也要透传

    n-image 的预览大图若另起一层 DOM,确认预览用的 img 同样带上 referrerpolicy(当前通过 img-props 一般可覆盖主图;若自定义预览组件,需单独处理)。

  3. 安全与合规

    no-referrer 会隐藏来源信息。仅用于展示外链资源时是常见做法;不要把它当成绕过业务鉴权的通用方案。

  4. 生产环境是否也要加

    正式域名通常已在白名单,可不依赖该属性。但加上一般无副作用,可减少「测试能看、线上偶发裂图」的差异;团队可统一在展示 1688 图的组件上默认开启。

  5. CSS / 背景图无效

    referrerpolicy 只作用于 <img>(以及部分带该属性的请求)。background-image: url(...) 不能 通过该属性控制 Referer,外链背景图仍可能被防盗链拦截,需改用 <img> 或服务端代理。

推荐落地方式

在需要展示 1688 图的列表 / 抽屉 / 详情中,统一加上 no-referrer

使用 n-image

vue 复制代码
<n-image
  :img-props="{ referrerpolicy: 'no-referrer' }"
  :src="isAliCdn(url) ? url : getPathImage(url, 120, 120)"
  :preview-src="isAliCdn(url) ? url : getPathImage(url, 0, 0)"
/>

使用原生 <img>

vue 复制代码
<img
  referrerpolicy="no-referrer"
  :src="isAliCdn(url) ? url : getPathImage(url, 120, 120)"
  alt="商品图"
/>

可抽一个小工具函数:

ts 复制代码
export const isAliCdn = (url = '') =>
  url.includes('cbu01.alicdn.com') || url.includes('global-img-cdn.1688.com')

后续新页面复制同一模式,避免测试环境再次出现「1688 图全裂」的问题。

小结

项目 说明
现象 测试环境 1688 图片裂图,正式环境正常
根因 CDN Referer 防盗链,测试域名不在白名单
手段(n-image :img-props="{ referrerpolicy: 'no-referrer' }"
手段(原生 img referrerpolicy="no-referrer"
效果 请求图片时不带 Referer,测试环境可正常显示
项目示例 src/views/product/sourceModel.vue

一句话:测试环境显示不了 1688 图时,优先给 n-image / <img> 加上 referrerpolicy: 'no-referrer'