Home >Web Front-end >JS Tutorial >Serving static files with Node

Serving static files with Node

不言
不言Original
2018-07-07 17:18:211206browse

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.

Preface

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.

Create a 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.

Use STREAM.PIPE() to optimize data transmission

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?

Understanding streams and pipes

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'))

Run

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.
Serving static files with Node

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.

Handling server errors

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('服务器内部错误')
  })

Use fs.stat() to implement error handling

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)
Note

The 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.

Summary

After 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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn