使用Apollo Server渲染自定义着陆页时图片无法显示的问题求助
解决Apollo Server自定义着陆页图片无法加载的问题
这个问题的核心原因是:Apollo Server默认不会自动托管你的public目录作为静态资源目录。当你直接在本地打开index.html时,浏览器是从本地文件系统读取图片,相对路径./public/images/api-screen.jpg能正常定位到文件;但当通过Apollo Server返回着陆页HTML时,浏览器会向服务器发起图片请求,而Apollo Server本身没有配置对应的路由来返回这张图片,自然就加载失败了。
下面给你几个可行的解决方案:
方案1:用Express托管静态资源(推荐,适合大多数Node.js项目)
如果你的项目已经在用Express(或者可以集成Express),可以通过express.static中间件把public目录托管成静态资源,这样服务器就能处理图片的请求了。
步骤:
- 确保已经安装了Express(如果没有,执行
npm install express) - 修改你的
app.js代码,集成Express并托管静态资源:
const express = require('express'); const { ApolloServer } = require('apollo-server-express'); // 创建Express实例 const app = express(); // 托管public目录,这样访问/public/*路径就能获取对应文件 app.use(express.static('public')); const server = new ApolloServer({ schema: schemaWithMiddleware, context: ({ req, res }) => { return { req, res }; }, formatError: (err) => { // logger.info(err); return err; }, plugins: [{ async serverWillStart() { return { async renderLandingPage() { // 修改图片路径为绝对路径,对应Express托管的资源 const html = `<!DOCTYPE html> <html> <head> </head> <body> <img src="/public/images/api-screen.jpg" style="width:100%"> </body> </html>`; return { html }; } } } } ] }); // 启动Apollo Server并挂载到Express async function startServer() { await server.start(); server.applyMiddleware({ app }); app.listen({ port: 4000 }, () => { console.log(`Server ready at http://localhost:4000${server.graphqlPath}`); }); } startServer();
方案2:用Apollo Server Standalone模式配置静态资源
如果你用的是Apollo Server的Standalone模式(不需要Express),可以在启动时直接配置静态资源目录:
const { ApolloServer } = require('@apollo/server'); const { startStandaloneServer } = require('@apollo/server/standalone'); const server = new ApolloServer({ schema: schemaWithMiddleware, context: ({ req, res }) => { return { req, res }; }, formatError: (err) => { // logger.info(err); return err; }, plugins: [{ async serverWillStart() { return { async renderLandingPage() { // 这里路径简化为/images/...,因为static配置会把public目录映射到根路径 const html = `<!DOCTYPE html> <html> <head> </head> <body> <img src="/images/api-screen.jpg" style="width:100%"> </body> </html>`; return { html }; } } } } ] }); // 启动时配置静态资源路径 const { url } = await startStandaloneServer(server, { listen: { port: 4000 }, static: { path: './public', // 指定静态资源目录 }, }); console.log(`Server ready at ${url}`);
方案3:将图片转为Base64内嵌到HTML(适合小图片)
如果你的图片体积不大,可以把它转换成Base64编码,直接内嵌到HTML中,这样就不需要依赖静态资源服务了。
你可以用在线工具或者Node.js脚本把api-screen.jpg转换成Base64,然后修改HTML的img标签:
<img src="data:image/jpeg;base64,[你的Base64编码内容]" style="width:100%">
这种方式的好处是不需要额外配置服务器,但大图片会导致HTML体积过大,影响加载速度,所以只推荐小图片使用。
内容的提问来源于stack exchange,提问作者Saswat
相关产品推荐
相关产品推荐

