【问题标题】:Access both static content and API with Express使用 Express 访问静态内容和 API
【发布时间】:2018-08-24 16:36:02
【问题描述】:

我在/api 有一个 Express REST API,我想在/ui 显示一个前端。我有这个:

api.js

const STATIC_FILES_PATH = path.resolve(__dirname, '..', 'frontend', 'build');
app.use(express.static(STATIC_FILES_PATH));
app.get('/ui', (_, res) => {
    res.sendFile(path.resolve(STATIC_FILES_PATH, 'index.html'));
});

app.get('/api/stuff', (req, res) => {
    //do stuff
});

当我导航到/api/stuff 时,我仍然看到前端而不是 API 响应。无论 URI 是什么,它总是显示前端网页。

我做错了什么?

编辑

这是我的项目结构:

/api
    api.js 
/frontend
    /build
        index.html

当我导航到 /api/stuff 时,在我的 Chrome 控制台中,我看到了 HTTP 304!它会将我重定向到前端(缓存),而不是向我显示 JSON 结果(API 响应)。

【问题讨论】:

  • 如果不确切知道您希望将哪些 URL 映射到文件系统中的哪些文件,我们无法真正建议正确使用 express.static(),我们需要查看文件层次结构并知道 __dirname 的位置该层次结构中的点。另外,我认为您想要path.join(),而不是path.resolve()。而且,您的STATIC_FILES_PATH 中没有匹配的/api 至关重要。
  • 转到浏览器中的网络选项卡,查看当您将/api/stuff 输入 URL 栏时从服务器返回的确切内容。如果它不是您的app.get('/api/stuff', ...) 处理程序发送的内容,那么您的express.static() 必须以某种方式匹配/api/stuff。另外,在你的路由处理程序中添加一个console.log("in api/stuff route"),这样你就可以知道它是否被调用了。
  • 问题已编辑。我收到 HTTP 304 并重定向到前端。如何禁用此行为?
  • 我尝试使用您的代码作为基础来重现此内容,但一切正常。您的问题中一定缺少一些导致问题的东西。您可能需要考虑创建一个minimal reproducible example
  • 我真的不知道为什么会这样,但 Express 正在缓存东西。我找到了一个可行的解决方案。我要发了!

标签: node.js api express


【解决方案1】:

添加此中间件后:

app.get('/*', (req, res, next) => {
    res.setHeader('Last-Modified', (new Date()).toUTCString());
    next();
});

它工作正常。似乎 Express 正在缓存东西。谢谢大家!

【讨论】:

  • 缓存静态内容是一项理想的 http 功能,可以提高性能并节省带宽。为什么它会给你带来麻烦?而且,为什么需要禁用它?如果您希望特定页面不被缓存或具有更短的到期时间,您可以为这些页面指定。当有很多真正的静态页面时关闭所有缓存会适得其反。
  • 感谢您的评论。问题是即使我想要 API 结果而不是静态内容,快递也会显示缓存的静态内容!
【解决方案2】:

使用这个 sn-p 更改您的代码,它经过测试并且可以正常工作。

api.js

const express = require('express');
const app = express();
const path = require('path');

const STATIC_FILES_PATH = path.resolve(__dirname, 'frontend', 'build');

app.use(express.static(STATIC_FILES_PATH));

app.get('/ui', (req, res, next) => {
    res.sendFile(path.resolve(STATIC_FILES_PATH, 'index.html'));
});

app.get('/api/stuff', (req, res, next) => {
    res.json({title: 'staff'});
});

app.listen(3000);

【讨论】:

  • 谢谢。你能告诉我你的代码和我的有什么不同吗?
  • 技术上没有什么不同。我检查了您的代码并在我的 PC 上运行,它运行正确并在单独的页面中显示 /api/staff/ui。致以最诚挚的敬意。
  • 我收到 HTTP 304 并被重定向到前端。这是为什么呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多