使用Express.js处理静态文件

268

我想将index.html/media子目录作为静态文件提供服务。索引文件应该在/index.html/ URL上都提供服务。

我有

web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));

但是第二行显然服务于整个__dirname,包括其中的所有文件(不仅仅是index.htmlmedia),这不是我想要的。

我也尝试过

web_server.use("/", express.static(__dirname + '/index.html'));

但是访问基本URL / 然后会导致请求到 web_server/index.html/index.html (双重 index.html 组件),这当然会失败。

有什么想法吗?


顺便说一下,在Express中我找不到任何关于这个主题(static() + 它的参数)的文档...令人沮丧。如果有文档链接那就更好了。

6
自从 Express 4.x 版本起,express.static() 方法是由 serve-static 中间件处理的。您可以在 https://www.npmjs.com/package/serve-static 或 https://github.com/expressjs/serve-static 查找其文档。 - Anm
有人能解释一下什么是“服务器作为静态文件”吗? - Abhi
在动态Web应用程序中,例如使用Express时,页面内容是由应用程序创建或生成的。另一方面,静态文件从静态目录层次结构中(大多数情况下)未经修改地提供。例如,虽然页面可能会更改,但图像文件、CSS文件和Javascript文件不会更改。 - Philip Callender
请查看以下链接:http://only4ututorials.blogspot.com/2017/05/how-to-serve-static-file-in-express-js.html - Dexter
这里我制作了一个类似目的的视频。它使用express和serve-index在局域网上创建完整的文件共享解决方案。https://youtu.be/4S6doMsaT78 - Yogesh Jog
12个回答

225

如果您拥有这个设置

/app
   /public/index.html
   /media

那么这样做应该会得到你想要的结果。

var express = require('express');
//var server = express.createServer();
// express.createServer()  is deprecated. 
var server = express(); // better instead
server.configure(function(){
  server.use('/media', express.static(__dirname + '/media'));
  server.use(express.static(__dirname + '/public'));
});

server.listen(3000);
这个诀窍是将这行代码作为最后一个备选项。
server.use(express.static(__dirname + '/public'));

关于文档,由于Express使用了Connect中间件,所以我觉得直接查看Connect的源代码更容易。

例如这一行显示了index.html得到了支持: https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140


22
Application.configure()在3.x版本中被标记为过时,并在4.x版本中被移除。请参考ChrisCantrell的答案以获取更新后的示例。 - Anm
__dirname是什么?它的值是什么? - Abhi
1
过时的,不适用于最新的Express。 - John Heeter

158
在最新版本的Express中,“createServer”已被弃用。这个例子对我有效:
var express = require('express');
var app = express();
var path = require('path');

//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); //  "public" off of current is root

app.listen(80);
console.log('Listening on port 80');

__dirname是一个关键字吗? - Mohammad Faizan khan
6
这是一个全局变量,位于你的Node.js模块中。http://nodejs.org/docs/latest/api/globals.html#globals_dirname - ChrisCantrell
7
__dirname并不是全局变量,而是每个模块本地的变量。 - Mohammad Faizan khan
2
这是Python中__file__的等效写法,您可以使用os.path.dirname(os.path.realpath(__file__))来获取。 - Abdelouahab
@ChrisCantrell 如果我有一个文件在 public/teams/logo.png,我该如何将其添加到静态文件夹中? - michal

118
express.static() 需要的第一个参数是目录的 路径,而不是文件名。建议创建另一个子目录来包含你的 index.html 文件并使用它。
在 Express 中提供静态文件 文档,或 更详细的 serve-static 文档,包括 默认行为为提供 index.html 文件

默认情况下,此模块会在请求目录时发送“index.html”文件作为响应。要禁用此功能,请设置为 false 或传递一个字符串或数组以指定新的索引顺序。


7
仅供参考,它会默认提供该其他目录下的index.html文件。 - TheSteve0
如果只有一个参数 - 那么 express.static 期望这个参数是路径... - Seti
旁边的问题是,例如如何使“/”从公共文件夹呈现“/welcome.html”?目前我使用“res.sendFile”从服务器加载文件(因此不使用它是公共文件的事实),但也许重写/重定向可能更合适? - Eric Burel

59

res.sendFileexpress.static都可以用于此

var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');

// viewed at http://localhost:8080
app.get('/', function(req, res) {
    res.sendFile(path.join(public, 'index.html'));
});

app.use('/', express.static(public));

app.listen(8080);

其中public是客户端代码所在的文件夹

正如建议 by @ATOzTOA澄清 by @Vozziepath.join将要连接的路径作为参数,+将单个参数传递给路径。


3
path.join 接受要连接的路径作为参数,而 + 则将单个参数传递给路径。 - ATOzTOA
@ATOzTOA 你能否多解释一下? - Zameer Ansari
@ATOzTOA所说的是你应该将path.join(public + 'index.html')更改为 path.join(public, 'index.html')。同时,将__dirname + "/public/"更改为path.join(__dirname,'public') - Vozzie
2
这帮助我将静态网站与API结合在一起。 - Jeff Beagley

10
const path = require('path');

const express = require('express');

const app = new express();
app.use(express.static('/media'));

app.get('/', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});

app.listen(4000, () => {
    console.log('App listening on port 4000')
})

7
如果您有一个复杂的文件夹结构,例如:
- application
     - assets
         - images
             - profile.jpg
     - web
     - server
        - index.js

如果您想从index.js提供assets/images,请按照以下步骤操作:
app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))

在浏览器中查看

http://localhost:4000/images/profile.jpg

如果您需要更多的澄清,请评论,我会进行详细说明。

我的资产文件夹包含CSS、JS和图像。我如何使用这种方法获取它们。注意:我也有相同的文件夹结构。@SaahityanVigneswaran - user17896109

5
在你的app.js中使用以下内容:
app.use(express.static('folderName'));

(folderName是一个包含文件的文件夹) - 记住这些资产可以通过服务器路径直接访问(例如,http://localhost:3000/abc.png (其中 abc.png 在 folderName 文件夹中)


3

使用npm安装serve-index模块

var express    = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))

// Listen
app.listen(port,  function () {
  console.log('listening on port:',+ port );
})

1

我想补充一些Express文档上的内容,有时在教程或其他文章中会被误读。

app.use(mountpoint, middleware) 

挂载点是一个虚拟路径,它不在文件系统中(即使它实际上存在)。中间件的挂载点是app.js文件夹。

现在

app.use('/static', express.static('public')`

将带有路径/static/hell/meow/a.js的文件发送到/public/hell/meow/a.js


0

当我提供HTML文件的链接时,出现了这个错误。

之前:

<link rel="stylesheet" href="/public/style.css">

之后:

<link rel="stylesheet" href="/style.css">

我刚刚从链接中删除了静态目录路径,错误就消失了。这解决了我的错误,还有一件事,不要忘记在创建服务器的地方添加这行代码。

var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接