You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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目录托管成静态资源,这样服务器就能处理图片的请求了。

步骤:

  1. 确保已经安装了Express(如果没有,执行npm install express)
  2. 修改你的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:22:40