如何使用 Node.js 提供图像
我的徽标位于 public/images/logo.gif
中。这是我的nodejs代码。
http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain' });
res.end('Hello World \n');
}).listen(8080, '127.0.0.1');
它可以工作,但是当我请求 localhost:8080/logo.gif 时,我显然没有得到徽标。
我需要做哪些改变才能提供图像。
I have a logo that is residing at the public/images/logo.gif
. Here is my nodejs code.
http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain' });
res.end('Hello World \n');
}).listen(8080, '127.0.0.1');
It works but when I request for localhost:8080/logo.gif
then I obviously don't get the logo.
What changes I need to do to serve an image.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
2016 年更新
使用 Express 和不使用 Express 的示例实际工作
这个问题已有 5 年多了,但每个答案都有一些问题。
TL;DR
向下滚动查看使用以下方式提供图像的示例:
express.static
express
connect
http
net
所有示例也位于 GitHub 上:https://github.com /rsp/node-static-http-servers
测试结果可在特拉维斯: https://travis-ci.org/rsp/node-static-http -servers
简介
自从提出这个问题以来已经过去 5 年多了,只有一个正确答案< /a> 通过generalhenry 但即使该答案对代码没有问题,它似乎在接收方面存在一些问题。有人评论说,它“除了如何依靠别人来完成工作之外,没有解释太多”,而有多少人投票赞成这一评论的事实清楚地表明,很多事情需要澄清。
首先,“如何使用 Node.js 提供图像”的一个好答案不是从头开始实现静态文件服务器并且做得很糟糕。一个好的答案是使用像 Express 这样正确完成工作的模块。
回答评论说使用 Express“除了如何依靠别人来完成工作之外没有解释太多”,应该注意的是,使用
http
模块已经依赖其他人来完成工作。如果有人不想依赖任何人来完成工作,那么至少应该使用原始 TCP 套接字 - 我在下面的一个示例中就是这样做的。更严重的问题是,这里所有使用
http
模块的答案都损坏。它们引入了竞争条件、不安全的路径解析(这将导致路径遍历漏洞)、阻塞 I/O(这将导致路径遍历漏洞)完全无法服务任何并发请求以及其他微妙的问题 - 它们作为问题所询问内容的示例完全被破坏,但它们已经使用了http 提供的抽象
模块而不是使用 TCP 套接字,因此它们甚至不像他们声称的那样一切都从头开始。如果问题是“如何从头开始实现静态文件服务器,作为学习练习”,那么无论如何应该发布如何做到这一点的答案 - 但即便如此,我们也应该期望它们至少是正确的。此外,假设想要提供图像的人可能希望在将来提供更多图像,这并不是没有道理的,因此有人可能会说,编写一个只能提供具有硬编码路径的单个文件的特定自定义静态文件服务器是有点短视。似乎很难想象任何搜索如何提供图像的答案的人都会满足于仅提供单个图像的解决方案,而不是提供任何图像的通用解决方案。
简而言之,问题是如何提供图像,答案是使用适当的模块以安全、高性能和可靠的方式来实现这一点,即可读、可维护且面向未来- 证明,同时使用专业节点开发的最佳实践。但我同意,对这样的答案的一个很好的补充是展示一种手动实现相同功能的方法,但遗憾的是到目前为止,每一次尝试都失败了。这就是我写一些新例子的原因。
在简短的介绍之后,下面是我在 5 个不同的抽象级别上完成这项工作的五个示例。
最低功能
每个示例都提供来自
public
目录的文件,并支持以下最低功能:index.html 作为默认目录索引,
我在 Node 版本 4、5、6 和 7 上测试了每个版本。
express.static
版本使用
express.static
express
模块。该示例功能最多,代码量最少。
express
此版本使用
express
模块,但没有express.static
中间件。提供静态文件是使用流作为单个路由处理程序实现的。此示例具有简单的路径遍历对策,并支持有限的大多数
常见 MIME 类型
。connect
此版本使用
connect
模块,该模块是比express
低一级的抽象。此示例具有与
express
版本类似的功能,但使用的 API 级别稍低。http
此版本使用
http
模块是 Node.js 中 HTTP 的最低级别 API。此示例具有与
connect
版本类似的功能,但使用了更低级别的 API。net
此版本使用
net
模块,它是 Node.js 中 TCP 套接字的最低级别 API。此示例具有
http
版本的一些功能,但从头开始实现了最小且不完整的 HTTP 协议。由于它不支持分块编码,因此在发送响应之前将文件加载到内存中以了解文件的大小,因为先统计文件然后加载会引入竞争条件。下载示例
我在 GitHub 上发布了所有示例并附有更多说明。
express.static
、express
、connect
、http
和net
的示例:其他仅使用
express.static
的项目:测试
测试结果可在 Travis 上获取:
一切都在 Node 版本上进行了测试4、5、6 和 7。
另请参阅
其他相关答案:
2016 Update
Examples with Express and without Express that actually work
This question is over 5 years old but every answer has some problems.
TL;DR
Scroll down for examples to serve an image with:
express.static
express
connect
http
net
All of the examples are also on GitHub: https://github.com/rsp/node-static-http-servers
Test results are available on Travis: https://travis-ci.org/rsp/node-static-http-servers
Introduction
After over 5 years since this question was asked there is only one correct answer by generalhenry but even though that answer has no problems with the code, it seems to have some problems with reception. It was commented that it "doesn't explain much other than how to rely on someone else to get the job done" and the fact how many people have voted this comment up clearly shows that a lot of things need clarification.
First of all, a good answer to "How to serve images using Node.js" is not implementing a static file server from scratch and doing it badly. A good answer is using a module like Express that does the job correctly.
Answering comments that say that using Express "doesn't explain much other than how to rely on someone else to get the job done" it should be noted, that using the
http
module already relies on someone else to get the job done. If someone doesn't want to rely on anyone to get the job done then at least raw TCP sockets should be used instead - which I do in one of my examples below.A more serious problem is that all of the answers here that use the
http
module are broken. They introduce race conditions, insecure path resolution that will lead to path traversal vulnerability, blocking I/O that will completely fail to serve any concurrent requests at all and other subtle problems - they are completely broken as examples of what the question asks about, and yet they already use the abstraction that is provided by thehttp
module instead of using TCP sockets so they don't even do everything from scratch as they claim.If the question was "How to implement static file server from scratch, as a learning exercise" then by all means answers how to do that should be posted - but even then we should expect them to at least be correct. Also, it is not unreasonable to assume that someone who wants to serve an image might want to serve more images in the future so one could argue that writing a specific custom static file server that can serve only one single file with hard-coded path is somewhat shortsighted. It seems hard to imagine that anyone who searches for an answer on how to serve an image would be content with a solution that serves just a single image instead of a general solution to serve any image.
In short, the question is how to serve an image and an answer to that is to use an appropriate module to do that in a secure, performant and reliable way that is readable, maintainable and future-proof while using the best practice of professional Node development. But I agree that a great addition to such an answer would be showing a way to implement the same functionality manually but sadly every attempt to do that has failed so far. And that is why I wrote some new examples.
After this short introduction, here are my five examples doing the job on 5 different levels of abstraction.
Minimum functionality
Every example serves files from the
public
directory and supports the minimum functionality of:index.html
as a default directory indexI tested every version on Node versions 4, 5, 6 and 7.
express.static
This version uses the
express.static
built-in middleware of theexpress
module.This example has the most functionality and the least amount of code.
express
This version uses the
express
module but without theexpress.static
middleware. Serving static files is implemented as a single route handler using streams.This example has simple path traversal countermeasures and supports a limited set of most
common MIME types
.connect
This version uses the
connect
module which is a one level of abstraction lower thanexpress
.This example has similar functionality to the
express
version but using slightly lower-lever APIs.http
This version uses the
http
module which is the lowest-level API for HTTP in Node.This example has similar functionality to the
connect
version but using even more lower-level APIs.net
This version uses the
net
module which is the lowest-level API for TCP sockets in Node.This example has some of the functionality of the
http
version but the minimal and incomplete HTTP protocol has been implemented from scratch. Since it doesn't support chunked encoding it loads the files into memory before serving them to know the size before sending a response because statting the files and then loading would introduce a race condition.Download examples
I posted all of the examples on GitHub with more explanation.
Examples with
express.static
,express
,connect
,http
andnet
:Other project using only
express.static
:Tests
Test results are available on Travis:
Everything is tested on Node versions 4, 5, 6, and 7.
See also
Other related answers:
我同意其他海报的观点,最终,你应该使用一个框架,例如 Express.. 但首先你还应该了解如何在没有库的情况下做一些基本的事情,以真正理解库为你抽象的内容..步骤是
代码看起来像这样(未经测试)
I agree with the other posters that eventually, you should use a framework, such as Express.. but first you should also understand how to do something fundamental like this without a library, to really understand what the library abstracts away for you.. The steps are
The code would look something like this (not tested)
您应该使用 express 框架。
然后
URL localhost:8080/images/logo.gif 应该可以工作。
You should use the express framework.
and then
and then the URL localhost:8080/images/logo.gif should work.
为时已晚,但对某人有帮助,
如果您的目录结构如下所示,我正在使用
node version v7.9.0
和express version 4.15.0
:server.js 代码:
It is too late but helps someone, I'm using
node version v7.9.0
andexpress version 4.15.0
if your directory structure is something like this:
server.js code:
根据要求的香草节点版本:
Vanilla node version as requested:
我喜欢使用 Restify 来实现 REST 服务。就我而言,我创建了一个 REST 服务来提供图像,然后如果图像源返回 404/403,我想返回替代图像。这是我结合这里的一些内容想到的:
I like using Restify for REST services. In my case, I had created a REST service to serve up images and then if an image source returned 404/403, I wanted to return an alternative image. Here's what I came up with combining some of the stuff here:
这可能有点偏离主题,因为您具体询问的是通过 Node.js 提供静态文件(其中
fs.createReadStream('./image/demo.jpg').pipe(res)
实际上是一个好主意),但在生产中,您可能希望让 Node 应用程序处理无法以其他方式处理的任务,并将静态服务卸载到 Nginx 等。这意味着应用程序内部的编码更少,效率更高,因为反向代理在设计上就是理想的选择。
This may be a bit off-topic, since you are asking about static file serving via Node.js specifically (where
fs.createReadStream('./image/demo.jpg').pipe(res)
is actually a good idea), but in production you may want to have your Node app handle tasks, that cannot be tackled otherwise, and off-load static serving to e.g Nginx.This means less coding inside your app, and better efficiency since reverse proxies are by design ideal for this.
这种方法对我有用,它不是动态的,而是开门见山:
This method works for me, it's not dynamic but straight to the point:
让我对上面的答案进行补充,优化图像和提供响应式图像可以显着缩短页面加载时间,因为超过 90% 的网络流量都是图像。您可能想要使用 JS / Node 模块预处理图像,例如 imagemin 和相关插件,最好是在使用 Grunt 或 Gulp 的构建过程中。
优化图像是指寻找理想的图像类型,并选择最佳的压缩方式以实现图像质量和文件大小之间的平衡。
提供响应式图像意味着自动为每个图像创建多种尺寸和格式,并在 HTML 中使用
srcset
允许您提供最佳图像集(即理想的格式和尺寸) ,从而为每个浏览器提供最佳文件大小)。构建过程中的图像处理自动化意味着将其合并一次,然后进一步呈现优化的图像,所需的额外时间最少。
关于响应式图片的一些精彩读物,缩小 一般来说,imagemin 节点模块和 使用 srcset。
Let me just add to the answers above, that optimizing images, and serving responsive images helps page loading times dramatically since >90% of web traffic are images. You might want to pre-process images using JS / Node modules such as imagemin and related plug-ins, ideally during the build process with Grunt or Gulp.
Optimizing images means processing finding an ideal image type, and selecting optimal compression to achieve a balance between image quality and file size.
Serving responsive images translates into creating several sizes and formats of each image automatically and using
srcset
in your HTML allows you to serve optimal image set (that is, the ideal format and dimensions, thus optimal file size) for every single browser).Image processing automation during the build process means incorporating it up once, and presenting optimized images further on, requiring minimum extra time.
Some great read on responsive images, minification in general, imagemin node module and using srcset.
Express 支持 HTTP/3 吗?没有。
HTTP/2 怎么样?没有。
我想未来的证明没有成功。
当标准发生变化时,依赖的模块不能快速更新的问题。请注意。
Does express support HTTP/3? Nope.
How about HTTP/2? Nope.
I guess future proof didn't work out.
The problem of depending on a module that isn't updated quickly when standards change. Be advised.