Home > Article > Web Front-end > Serving static files with Node
This article mainly introduces the use of Node to provide static file services. It has a certain reference value. Now I share it with you. Friends in need can refer to it.
For a For web applications, it is often necessary to serve static files (CSS, JavaScript, images). This article will introduce how to make your own static file server.
Each static file server has a root directory
, which is the basic directory that provides file services. So we need to define a root variable on the server we are about to create, which will serve as the root directory of our static file server:
var http = require('http') var join = require('path').join var fs = require('fs') var root = __dirname
__dirname is a magical variable in Node, and its value is where the file is located The path to the directory. In this example, the server will use the directory where this script is located as the root directory of the static files.
With the path of the file, the content of the file also needs to be transferred.
This can be done with fs.ReadStream
, which is one of the Stream classes in Node. A successful call to fs.createReadStream() returns a new fs.ReadStream object.
The following code implements a simple but fully functional file server.
var server = http.createServer(function(req, res){ let path = join(root, req.url) let stream = fs.createReadStream(path) stream.on('data', function(chunk){ res.write(chunk) }) stream.on('end', function(){ res.end() }) }) server.listen(3000)
This file server generally works, but there are many details to consider. Next, we need to optimize data transmission and streamline the server code.
Although the above code looks good, Node also provides a more advanced implementation mechanism: Stream.pipe()
. Using this method can greatly simplify the server code. The optimized code is as follows:
var server = http.createServer(function(req, res){ let path = join(root, req.url) let stream = fs.createReadStream(path) stream.pipe(res) }) server.listen(3000)
Is this way of writing simpler and clearer?
Flow is a very important concept in Node. You can think of the pipes in Node as water pipes. If you want a certain source (such as a water heater) to flow out If the water flows to a destination (such as a kitchen faucet), you can add a pipe in the middle to connect them, so that the water will flow along the pipe from the source to the destination.
The same is true for the pipeline in Node, but what flows in it is not water, but data from the source (i.e. ReadableStream
). The pipeline can allow them to "flow" to a certain destination (i.e. WritableStream
). You can use the pipe method to connect pipes:
ReadableStream.pipe(WritableStream)
Reading a file (ReadableStream) and writing the contents to another file (WritableStream) uses a pipe:
let readStream = fs.createReadStream('./original.txt') let writeStream = fs.createWriteStream('./copy.txt') readStream.pipe(writeStream)
All ReadableStreams can access any WritableStream. For example, the HTTP request (req) object
is a ReadableStream, and you can let the contents flow to a file:
req.pipe(fs.createWriteStream('./req-body.txt'))
Now let's run the above code, we are at the root Place a picture in the directory, such as peiqi.jpg.
Enter http://127.0.0.1:3000/peiqi.jpg
in the browser, and you will find that the cute peiqi has appeared in front of you. peiqi.jpg
is sent from the http server to the client (browser) as the response body.
Although it has tasted success, this static file server is not complete enough because it is prone to errors. Imagine that if the user accidentally enters a resource that does not exist, such as abc.html, the server will crash immediately. So we have to add an error handling mechanism to this file server to make it robust
.
In Node, all classes that inherit EventEmitter may emit error events. In order to monitor errors, register an error event handler (such as the following code) on fs.ReadStream, and return response status code 500 to indicate an internal server error:
stream.on('error', function(err){ res.statusCode = 500 res.end('服务器内部错误') })
We can use fs.stat()
to obtain relevant information about the file. If the file does not exist, fs.stat() will put ENOENT# in err.code. ##In response, you can then return error code 404 to indicate to the client that the file was not found. If fs.stat() returns other error codes, you can return the generic error code 500.
The refactored code is as follows:
var server = http.createServer(function(req, res){ let path = join(root, req.url) fs.stat(path, function(err, stat) { if (err) { if ('ENOENT' == err.code) { res.statusCode = 404 res.end('Not Found') } else { res.statusCode = 500 res.end('服务器内部错误') } } else { // 有该文件 res.setHeader('Content-Length', stat.size) var stream = fs.createReadStream(path) stream.pipe(res) stream.on('error', function(err) { // 如果读取文件出错 res.statusCode = 500 res.end('服务器内部错误') }) } }) }) server.listen(3000)NoteThe file server built in this section is a simplified version. If you want to put this into a production environment, you should check the validity of the input more thoroughly to prevent users from accessing parts of the content through directory traversal attacks that you did not intend to open to them. SummaryAfter reading this, I believe you are smart and have mastered how to use Node to create a static server. In the next article, I will introduce to you how to use Node to process files uploaded by users and Store in the server. The above is the entire content of this article. I hope it will be helpful to everyone's study. For more related content, please pay attention to the PHP Chinese website! Related recommendations:
Use Node to process file uploads
Interpret some of the Redux source code through ES6 writing
The above is the detailed content of Serving static files with Node. For more information, please follow other related articles on the PHP Chinese website!