This is the third day of my participation in Gwen Challenge

preface

Today, we are going to focus on the Http module in NodeJS. This module is the first module that every front-end development touches on NodeJS.

const http = require('http');
http.createServer((request, response) = > {
    response.end('Hello Nodejs');
}).listen(3000.() = > {
    console.log('server start up at 3000')})Copy the code

As mentioned above, we have created a very simple NodeJS service. Isn’t it very simple? That’s probably why it’s so popular. But as a test, so can, we can use this way to do something, but when we want to do more (maybe not and production), but such a service, is obviously unable to support our front page, commissioning that one of the most basic services available to include those parts to you? Specific as follows

Simply available services need to include those things

  1. Need to be able to handleget.postrequest
  2. rightpostProcessing of parameters
  3. Need to be able to handle static files
  4. Need to be able to handle cross-domain requests

Today, we will talk about the above four points, of course, there are many other places involved, such as FormData parameter processing, file parameter processing, middleware processing, etc. If you are interested in these, I recommend you to take a brief look at express or KOA API design, without looking at the source code. Developing a certain direction of processing and then comparing the source code is probably the most effective way to learn about NodeJS. Without further discussion, let’s look at one point at a time:

Process GET POST requests

Get/POST (if else);

const http = require('http');
http.createServer((request, response) = > {
    const {url, method} = request;
    if(url === '/' && method.toLowerCase() === 'get') {
        response.setHeader('Content-Type'.'text/plain; charset=utf-8')
        response.end("You visited the home page!");
    } else {
        response.statusCode = 404;
        response.end();
    }
    
}).listen(3000.() = > {
    console.log('server start up at 3000')})Copy the code

This is fine for some simple logic, but as we get more business involved, we’ll need to normalize the interface, not the way it is now. Write a JS, used to obtain a fixed folder under the JS file interface processing, specifically as follows:

// loader.js reads the routes file
const { readdir } = require("fs/promises")
module.exports = {
    load: (path, callback) = > {
        readdir(path)
        .then(files= > {
            files.forEach(filename= >{ callback(filename); }}})})// Write the route file
// index
module.exports = {
    'get /': (request, response) = > {
        response.setHeader('Content-Type'.'text/plain; charset=utf-8');
        response.end('Here's what's on the front page.');
    },
    'get /detail': (request, response) = > {
        response.setHeader('Content-Type'.'text/plain; charset=utf-8');
        response.end('This is the home page details')}}// home
module.exports = {
    'get /': (request, response) = > {
        response.setHeader('Content-Type'.'text/plain; charset=utf-8');
        response.end('Here's the contents of home');
    },
    'get /detail': (request, response) = > {
        response.setHeader('Content-Type'.'text/plain; charset=utf-8');
        response.end('This is the home details page')}}// httpService loads the file and executes the function
const http = require('http');
const { url } = require('inspector');
const { resolve } = require('path');
const { load } = require('./loader');
http.createServer((request, response) = > {
    let {url, method} = request;
    method = method.toLowerCase();
    load(resolve(__dirname, 'routes'), filename= > {
        const prefix = filename === 'index.js' ? ' ' : '/' + filename.split('. ') [0];
        const module = require(`./routes/${filename}`);
        Object.keys(module).forEach(str= > {
            let [currMethod, currUrl] = str.split(' ');
            currUrl = prefix + currUrl;
            if(url === currUrl && currMethod === method) {
                module[str](request, response)
            }
        })
    })
}).listen(3000.() = > {
    console.log('server start up at 3000')})Copy the code

As mentioned above, we have solved the if else nesting problem of the HTTP service. We can read and write the file every time, and call the function according to the configuration of the read. Then we can find that we cannot get the body data of the post. Keep reading:

Basic processing of post parameters

As we know, HTTP createServer provides both request parameters and response parameters based on streams. If the request type is POST, the parameters will be passed through streams. Therefore, we need to listen for methods that allow us to retrieve the complete parameters of HttpRequest. The specific code is as follows:

const http = require('http');
const { resolve } = require('path');
const { load } = require('./loader');
http.createServer((request, response) = > {
    let {url, method} = request;
    method = method.toLowerCase();
    // Post body processing
    const data = [];
    request.on('data'.(result) = > data.push(result));
    request.on('end'.() = > {
        request.data = Buffer.concat(data).toString()
        // compare url with method
        load(resolve(__dirname, 'routes'), filename= > {
            const prefix = filename === 'index.js' ? ' ' : '/' + filename.split('. ') [0];
            const module = require(`./routes/${filename}`);
            Object.keys(module).forEach(str= > {
                let [currMethod, currUrl] = str.split(' ');
                currUrl = prefix + currUrl;
                if(url === currUrl && currMethod === method) {
                    module[str](request, response)
                }
            })
        })
    })
    
}).listen(3000.() = > {
    console.log('server start up at 3000')})Copy the code

At this point, our request is actually available, but because of browser cross-domain limitations, the Ajax POST method does not return parameters correctly. What should we do? Let’s move on

Resolve cross-domain problems

CROS is one of the most commonly used HTTP header Settings in the world. CROS is the most common HTTP header Settings in the world. CROS is the most common HTTP header Settings in the world.

  1. Access-control-allow-origin adds the domain name that is currently requested to Allow Access
  2. Access-control-allow-headers: specifies whether the request Headers are allowed to be sent.
  3. Access-control-allow-credentials Allow carrying cookes

The specific code is as follows:

module.exports = {
    'post /': (request, response) = > {
        // Normal environment should not set *, for testing *
        response.setHeader('Content-Type'.'text/plain; charset=utf-8');
        response.setHeader('Access-Control-Allow-Origin'.The '*');
        response.setHeader('Access-Control-Allow-Headers'.The '*');
        response.setHeader('Access-Control-Allow-Credentials'.true);
        response.end('Here's the contents of home' + request.data);
    },
    'get /detail': (request, response) = > {
        response.setHeader('Content-Type'.'text/plain; charset=utf-8');
        response.end('This is the home details page')}}Copy the code

Resolve static file proxy issues

On the static file proxy problem, first we need to have a static file directory, in each request to enter, according to the request path and the static file directory together with the file retrieval, if there is, return the file, return 404, it is worth noting that, Normal file processing includes HTML/CSS /js/image/font/ etc. We may not be able to cover all the files. If you are interested, you can check the express.static source code to see how the framework level is handled.

const filename = resolve(__dirname, temp, url.slice(1));
stat(filename).then(
    result= > {
        if(result.isFile()) {
            readFile(filename)
            .then(result= >{ response.end(result); })}},err= > {
        response.statusCode = 404; response.end(); })Copy the code

conclusion

The above is all the content of today, you can put forward the module you want to see in the comment area, specific code address, you can also download express or KOA code to analyze their structure and function, there will be no small harvest!