Objective
These days in order to familiarize yourself with the vue.js framework and the use of Webpack, you are ready to build a simple Web application that publishes and browses Markdwon. Originally wanted to use bash scripts and BusyBox httpd as a background service, but bash script parsing and generation of JSON is very inconvenient, and in the Java language and feel that deployment is not convenient, so think of the use of node. js, so there is this blog post. (At the end of this article is the GitHub address of this code)
Simple example
First, Hello world
build the following directories, files, and content from the simplest start.
Establish project and run
Project
web-server+ | - server.js
Server.js
const http = require('http');http.createServer(function(request, response) { // 设置响应头 response.writeHeader(200, { "Content-Type" : "text/plain" }); // 响应主体为 "Hello world!" response.write("Hello world!"); response.end();})// 设置监听端口为9000.listen(9000);
Now, run the following command in the project directory, enter in the server.js
browser address bar localhost:9000
, and if all access is normal, the browser will display Hello world!
.
node server.js
Tip: ctrl+c
run with Stop script.
At this point a simple example runs successfully, and the following is an analysis of the code.
Code Analysis
First, server.js
node. JS is introduced in http模块
, which provides very low-level HTTP API support. Here you use the createServer()
method, which returns an http.server
instance that uses the method of the instance listen()
to set the listening port.
The createSever()
parameter that is filled in the method is a function that is automatically added as a callback function to the request事件
go, and its parameter types are respectively http.IncomingMessage
and http.ServerResponse
. In the body of the callback function, http.ServerResponse
the method is used to set the response header and the response body, and finally the end()
method ends the request.
Routing Features
The above example simply implements the simple request-response function, and now adds the ability to route to our web server. Now, modify the directory, file, and content to the following.
Implementing Simple routing
Project
web-server | - server.js+ | - router.js
Server.js
const http = require('http');const router = require('./router.js');function handleHello(request, response) { // 设置响应头 response.writeHeader(200, { "Content-Type" : "text/plain" }); // 响应主体为 "Hello world!" response.write("Hello world!"); response.end();}http.createServer(function(request, response) { // 注册路径和其对应回调函数 router.register(request, response, [ { 'url': '/hello', 'handler': handleHello } ]);})// 设置监听端口为9000.listen(9000);
Router.js
const url = require('url');exports.register = function(request, response, mapping) { // 解析请求路径 var pathName = url.parse(request.url).pathname; // 执行相应请求路径的回调函数 for(let i = 0, len = mapping.length;i < len;i++) { if(mapping[i].url === pathName) { mapping[i].handler(request, response); return; } } // 请求路径不存在返回404页面 response.writeHeader(404, { "Content-Type" : "text/html" }); response.end(`
Now, execute the server.js
script again, then the browser accesses localhost:9000\hello
Hello world!
the results, and the access to the other paths gets 404 pages.
The core implementation of this function is in router.js
, through the request path parsing, and then according to the pre-registered mapping
array, to find the corresponding path and execute the corresponding callback function.
Static resource Request The current routing function can only implement callback functions, and a Web server should have the ability to respond to static resource requests, and then we continue to retrofit it. Now, keep the server.js
content intact, changing only the router.js
contents (some of the code content is omitted).
Route.js
Const URL = require (' URL '), const PATH = require (' path '), const FS = require (' FS '), function GetErrorInfo (errorType) {//omitted Code}function writeerrorpage (response, ErrorType) {//Omit code}exports.register = function (request, response, mapping) {//Solution Analysis Request path var pathName = Url.parse (request.url). PathName; callback function to execute the corresponding request path for (Let i = 0, Len = mapping.length;i < len;i++) {if (Mapping[i].url = = = PathName) {mapping[ I].handler (request, response); Return }}//request path for file return file contents var = path.resolve (__dirname, '. ' + pathName); Fs.exists (file, function (exists) {//request path does not exist return 404 page if (!exists) {writeerrorpage (response, ' not_found '); } else {var stat = fs.statsync (file); The request path returns 403 pages for the directory if (Stat.isdirectory ()) {writeerrorpage (response, ' FORBIDDEN '); } else {Response.writeheader ($, {"Content-type": "Text/html"}); Response.End (Fs.readfilesync (file, ' Utf-8 ')); } } });}
The design of the behavior of the static resource request is to ensure that the callback function must be executed. When a static resource does not exist, it should return a non-existent error, and also set a rule that prohibits access to the directory.
Something Now, just the basic functionality of the Web server is implemented, and it has a lot of room for improvement. I open the project to GitHub and I'm interested in cloning it.