问题
网页在Windows直接运行的时候一切正常,但是通过docker以后,浏览器通过localhost:12345访问时,背景却无非正常显示,但是音乐播放器和别的功能模块却可以正常访问网络加载:
问题根源分析
这个问题的核心不在 Docker,而在于浏览器的工作方式以及图片服务器的安全策略。
- 环境变化:
- 直接在 Windows 运行: 当您直接双击打开 HTML 文件时,浏览器地址栏的地址是
file:///D:/my-website/index.html
。这属于本地文件协议。 - 通过 Docker 访问: 当您通过 Docker 访问时,浏览器地址栏的地址是
http://localhost:12345
。这属于 HTTP 协议。
- 直接在 Windows 运行: 当您直接双击打开 HTML 文件时,浏览器地址栏的地址是
- 关键概念:HTTP Referer (来源地址)
- 当浏览器从一个网页去请求另一个资源(比如图片、JS 文件)时,它通常会带上一个名为
Referer
的 HTTP 头信息,告诉目标服务器:“我是从哪个页面过来的”。 - 当您从
http://localhost:12345
访问图片时,浏览器对图片服务器发出的请求头里会包含Referer: http://localhost:12345/
。
- 当浏览器从一个网页去请求另一个资源(比如图片、JS 文件)时,它通常会带上一个名为
- 核心原因:防盗链策略 (Anti-Hotlinking Policy)
- 很多图床或内容网站(比如您链接中的
cnblogs.com
,zcool.cn
,itc.cn
等)为了节省自己的服务器带宽和成本,会设置防盗链。 - 它们的服务器会检查请求的
Referer
头。如果Referer
是一个它们不认识、不允许的域名(比如localhost
),服务器就会拒绝返回图片,通常会返回一个403 Forbidden
(禁止访问) 的错误。 - 而当您直接以
file:///
方式打开时,浏览器可能不发送Referer
头,或者发送一个服务器允许的空值,所以图片能够正常加载。 - 您的音乐播放器能正常工作,是因为它调用的 API (网易云音乐的 API) 是专门设计为可以被任何网站调用的,它不依赖
Referer
进行验证。
- 很多图床或内容网站(比如您链接中的
如何验证?
您可以通过浏览器的开发者工具轻松验证这一点:
- 在浏览器中打开
http://localhost:12345
页面。 - 按下
F12
键,打开“开发者工具”。 - 切换到 "Network" (网络) 选项卡。
- 刷新页面 (按
F5
或Ctrl+R
)。 - 在请求列表中,找到那些图片链接(可以按 "Img" 进行筛选)。
- 您会发现这些图片请求的状态 (Status) 很可能是红色的
403
或其他错误码。 - 点击其中一个失败的图片请求,在右侧查看 "Headers" (标头) -> "Request Headers" (请求标头),您就能清楚地看到
Referer: http://localhost:12345/
这一行。
解决方案
方案一:【快速修复 & 推荐尝试】修改网页的 Referrer Policy
我们可以告诉浏览器,在请求这个页面上的任何资源时,都不要发送 Referer
信息。
在您的 index.html
文件的 <head>
标签内,加入下面这行 <meta>
标签:
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>您的网页标题</title><meta name="referrer" content="no-referrer"></head>
原理: content="no-referrer"
指示浏览器在从您的页面发起任何跨域请求时,都省略 Referer
头部。很多图床服务器对于没有 Referer
的请求是放行的。
修改 index.html
保存后,您需要重新构建 Docker 映像并运行新的容器,因为旧容器里的文件不会自动更新。
# 1. 重新构建映像
docker build -t my-search-page .# 2. 停止并删除旧容器 (如果还在运行)
docker stop my-website-container
docker rm my-website-container# 3. 运行新容器 (假设您使用12345端口)
docker run --name my-website-container -d -p 12345:8080 my-search-page
★方案二:【长期 & 最可靠方案】本地化图片
将所有背景图片下载下来,放到您的项目文件夹中,例如创建一个 images
文件夹。
您的项目结构变为:
.
|-- my-website #工程文件夹
| |-- Dockerfile #构建 Docker 映像的“说明书”或“蓝图” 空白文本文件(注意,没有文件扩展名)
| |-- images #图片存放文件夹
| | `-- backgrounds #背景图片文件夹
| `-- index.html #网页
然后,修改您的 Dockerfile
,将整个 images
文件夹复制到容器里:
FROM nginxinc/nginx-unprivileged:alpine# 将所有网站文件(包括 images 文件夹)复制过去
COPY . /usr/share/nginx/html/EXPOSE 8080
注意:这里用 COPY .
复制了当前目录下的所有内容。
最后,修改 index.html
中的图片链接为相对路径:
backgrounds: [ "./images/backgrounds/wallpaper1.webp", "./images/backgrounds/wallpaper2.jpg", "./images/backgrounds/wallpaper3.jpeg", "./images/backgrounds/wallpaper4.jpeg", "./images/backgrounds/wallpaper5.jpg", "./images/backgrounds/wallpaper6.webp", "./images/backgrounds/wallpaper7.webp", "./images/backgrounds/wallpaper8.webp", "./images/backgrounds/wallpaper9.webp", "./images/backgrounds/wallpaper10.webp", "./images/backgrounds/wallpaper11.webp", "./images/backgrounds/wallpaper12.webp", "./images/backgrounds/wallpaper13.jpg", "./images/backgrounds/wallpaper14.webp", "./images/backgrounds/wallpaper15.webp", "./images/backgrounds/wallpaper16.webp", ],
优点:
- 完全可靠: 不再依赖外部图床的策略,不会因对方服务器故障或更改策略而失效。
- 性能可能更好: 所有资源都从同一个地方提供。
- 项目独立: 整个网站可以完全离线运行。
总结建议:
- 先尝试方案一,它最简单,只需修改一行 HTML 代码。
- 如果方案一无效(说明某些图床连没有
Referer
的请求也封禁了),或者为了让您的项目更稳定可靠,强烈推荐使用方案二。