node HTTP protocol building service

Summary

Browser (client) -> server interaction

1. Browser (client) -> server interaction

 initiate a request: request message
   Response request: Response message

   The message is: String

Request message object: request

2. Request message object: request

  • request line:
    • Request type: (get, post) Other request types will be exposed later request.method
    • Request url: The part after the domain name/url starting from / is the request url request.url
    • http protocol version number: http/1.1 request.httpVersion
  • Request header: request.headers returns an object let {host,connection} = request.headers
    There are some differences in the headers requested in each URL, but there will be some common header information. [Reference courseware]
    When you build your own service later, you can add custom header information by yourself
  • blank line
  • Request body:
    different from the request method
    • If it is a get request, there is no request body

      Other types have a request body
      Although get has no request body, it can display the data that needs to be passed to the server in the request string of the url address
      http://localhost/index.html?name=admin&pass=123456

      ?Parameter name=parameter value & amp;parameter name=parameter value This format is called request string/query string, which is appended to the requested url
      Use the url module to parse the string in the url into an object

      const url = require(‘url’)
      url.parse(request.url,true); //{name:admin,pass:123456}

    • The post request has a request body
      by event

       let s = ''
      request.on('data', chunk=>{
      s + =chunk;//chunk gets the requested data
      })
      \t
      request.on('end',()=>{
      console.log(s); //name=admin & amp;pass=123456
      response.end('xxx')
      })
      

Response message object: response

3. Response message: response

  • Response line:

    • http protocol version number

    • Response status code 200, 404 (not found), 500 (server related error) response.statusCode

    • Response status string response.statusMessage
      200 -> ok
      404 -> not found
      500 -> internal server error

      There is a one-to-one correspondence between the response status code and the response status string

  • Response header:
    response.setHeader('header name','header value')
    response.writeHead(response status code, {'header name':'header value'})

  • empty line:

  • Response body: The server gives the client a response result
    Image, text, json format string, website label content (html + css). . .

    response.end()

    response.write()

    write can be called multiple times and output multiple response results, but in the end it must rely on the end method

    Although the end method can be written multiple times, it can only execute the first end in the end, because once the program encounters end, it will directly respond to the client with the result of the response body

//Introduce http module url module
const http = require('http');
const url1 = require('url');
// build service object
const server = http.createServer( (request,response)=>{<!-- -->//request request message object response response message object
  const {<!-- -->method,url,httpVersion,headers} = request;//Get request type request url address request http protocol version number request header

  // Set the response header, two methods
  response.setHeader('Content-Type','text/html;charset=utf-8');
  response.writeHead(200,{<!-- -->'Content-Type':'text/html;charset=utf-8'});
  response.setHeader('a','100');//Custom response header information
  if(method === "GET"){<!-- -->
    // http://localhost/index.html?name=admin&pass=123456
    let data = url1.parse(url,true)//data.query attribute value is converted from string to object {name:admin,pass:123456}
    console.log(data.query,data.pathname);//pathname request url address
  }else if(method === "POST"){<!-- -->
    // Get the post request body through the event
    let str = '';
    // Receive request data
    request.on('data', chunk=>{<!-- -->
      str + = chunk;//request data
    })
    //Receive data complete
    request.on('end',()=>{<!-- -->
      response.end(str);//Set the response body
    })
  }
  
  response.end('Set content');//Set response body method one
  //Set response body method 2
  // response.write('content')
  // response.write('Content 1')
  // response.write('Content 2')
  // response.end('Set content 3');
});
//Set the listening port
server.listen(8080,()=>{<!-- -->
  console.log('service started successfully')
})

HTTP protocol

1. Concept

HTTP (hypertext transport protocol) protocol; Chinese called Hypertext Transfer Protocol

It is an application layer communication protocol based on TCP/IP

This protocol specifies the rules for communicating between a browser and a server of the World Wide Web.

The agreement mainly stipulates two aspects

  • Client: used to send data to the server, which can be called request message
  • Server: Return data to the client, which can be called a response message

Message: actually a bunch of strings

2. The composition of the request message 【Key points】

  • request line
  • request header
  • blank line
  • request body

3. HTTP request line content

  • request type (get, post, put, delete, etc.)

  • Request URL (Uniform Resource Locator)

    For example: http://www.baidu.com:80/index.html?a=100 &b=200#logo

    • http: protocol (https, ftp, ssh, etc.)
    • www.baidu.com domain name
    • 80 port number
    • /index.html path
    • a=100 & amp;b=200 query string (request string)
    • #logo hash (anchor link)
  • HTTP protocol version number

4. HTTP request header structure and common request headers

Format: header name: header value;

Common request headers are:

The request header can be customized by the programmer! ! !

Request Header Explanation
Host Host name
Connection Connection setting keep-alive (keep connection); close (close connection)
Cache-Control Cache-Control max-age = 0 (no cache)
Upgrade-Insecure-Requests Convert http requests in webpages into https requests (rarely used) old website upgrade
User-Agent User agent, client character The server can use this identifier to identify which client the request comes from. Generally, it is distinguished between PC and mobile.
Accept Set the browser Received data type
Accept-Encoding Set the received compression method
Accept-Language Set the received language q=0.7 as the preference coefficient, the full score is 1
Cookie Separate later

5. HTTP request body

The format of the request body content is very flexible,

(can be empty) ==> GET request,

(It can also be a string or JSON) ===》POST request

For example:

  • Request string (parameter name=parameter value & amp;parameter name=parameter value): keywords=mobile phone & amp;price=2000
  • JSON (the key name must be double quotes, and the key value must also be double quotes if it is a string): {“keywords”: “mobile phone”, “price”: 2000}

6. The composition of the response message and the response line

  • response line

    HTTP/1.1 200 OK
    
    • HTTP/1.1: HTTP protocol version number

    • 200: Response status code 404 Not Found 500 Internal Server Error

      There are also some status codes, refer to: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

    • OK: response status string

    There is a one-to-one correspondence between the response status code and the response string.

  • response header

 Cache-Control: cache control private private, only allows the client to cache data
 Connection link settings
 Content-Type:text/html;charset=utf-8 Set the data type and character set of the response body, the response body is html, and the character set is utf-8
Content-Length: The length of the response body, in bytes
  • blank line

  • response body

? The type of response body content is very flexible. Common types include HTML, css, js, image, JSON, video, audio, font…

7. Build WEB service

Create an HTTP server using nodejs

Three steps:

① Introduce http built-in module

const http = require("http")

② Create service

const server = http.createServer((request,response)=>{<!-- --> //Ordinary function or arrow function can be used
//According to the request, set the content of the response message
//end method can set the response body
response.end("xxx")
})
  • request: is an object that can get the data in the request message
  • response: is an object, you can set the data in the response message

③ Listening port

  • The port number:
  • It is the service window of the computer. There are 65536 service windows in total. The program can listen to the port to process the data of the specified port
  • Choice of common port numbers: 8000, 8080, 8888, 3000, 9000 The default port number is 80, which can be omitted in “browser request”

Other port numbers should be greater than 1024

server.listen(port number, callback function)

④ Corresponding port of browser request

http://127.0.0.1: port number
  • 127.0.0.1 always points to this machine, and the IP address is the only house number of the computer in the network.

  • IP addresses generally consist of four digits, ipv4 (version 4)

  • Get the ip address of a website:

ping domain name

FAQ:

(1) When the service has started

  • Want to modify the JS code, after refreshing the browser, it is found that the content of the page has not changed
Answer: After the JS code is modified, the service "must be restarted" (not re-run the file) to see the latest display results
  • Port number is occupied

Error: listen EADDRINUSE: address already in use :::8000

Solution 1: Stop the service currently running on the listening port [commonly used]

Answer: Find the corresponding command line window and use the "ctrl + c" key combination

Solution 2: Modify other port numbers to use

  • The response content is in Chinese, which is displayed as garbled characters in the browser
Answer: response.writeHead(200,{<!-- -->"Content-Type":"text/plain;charset=utf-8"}) #The default is text
//1. Import http module
const http = require('http');

//2. Create service
const server = http.createServer((request,response)=>{<!-- -->
    response.end('hello http');
})
//3. Listen port
server.listen(80,()=>{<!-- -->
    console.log('80 port service has started');
})

8. Get HTTP request data

If you want to get the requested data, you must pass the request object;

It contains the following parameters:

Parameter name Meaning Grammar Key points
method request method request.method *****
httpVersion request version request.httpVersion
url Request Path request.url *****
headers Request Header request.headers *****
on Request Body request.on(‘data’, function(chunk){})
request.on(‘end’, function(){});

Special Instructions:

1. request.url: only the path and query string can be obtained, but the domain name and protocol content in the url cannot be obtained;

2. request.headers: convert the request information into an object, and convert the attribute names into “lowercase”

3. About the path: If you only fill in the IP address or domain name information when visiting the website, the path requested at this time is “/”

4. About ip: ip is the unique house number of the computer in the network, ipv4 156.23.56.85

? 127.0.0.1 is always pointing to this machine

4. Regarding favicon.ico: This request is automatically sent by “Google Chrome”, and other browsers may not necessarily send it.

 Used to get the "small icon" of the current website

Exercise 1: According to the following requirements, build an http service and access it according to different url addresses

request type request address response body result
get /login login page
get /register Registration page
//1. Import http module
const http = require("http");
//2, create a service
const server = http.createServer((request,response)=>{<!-- -->
    let {<!-- -->url,method} = request; //Object deconstruction assignment
    //Set response header information
    //Solve Chinese garbled characters
    response.setHeader("Content-Type","text/html;charset=utf-8")
    if(url == "/register" & amp; & amp; method == "GET"){<!-- -->
        response.end("Registration page");
    }else if(url=="/login" & amp; & amp; method == "GET"){<!-- -->
        response.end("login page");
    }else{<!-- -->
        response.end("<h1>404 Not Found</h1>")
    }
})

//3, listening port
server.listen(8000,()=>{<!-- -->
   console.log('service starting....');
})

When the request url carries request parameters, you need to use the url module

① Introduce http built-in module

let http = require("http")

② Import the url module

let url = require("url");

③ Create service

let server = http.createServer((request,response)=>{<!-- -->
//Analyze for the url in the request
    //The second true means to convert the query attribute value from a string to an object
//Syntax: url.parse(request.url,true)
response.end("xxx")
})

Commonly used parameters in the url module

  • pathname: the path part in the url

  • query: query string object in url

③ Listening port

The port number:

  • It is the service window of the computer. There are 65536 service windows in total. The program can listen to the port to process the data of the specified port
  • Choice of common port numbers: 8000, 8080, 8888, 3000, 9000 The default port number is 80, which can be omitted in “browser request”
  • Other port numbers should be greater than 1024

Exercise 2: According to the following requirements, build an http service, access it according to different url addresses, and modify the background color of the page

For example:

/server?bg=yellowgreen

/server?bg=red

//1, introduce the http module
const http = require("http");
//2. Import the url module
const url = require("url");
//3, create a service
const server = http.createServer((request,response)=>{<!-- -->
    // console.log(url); //url is an object
    //If you want to parse the request address in the address bar, you need to call the parse method in the url object
    //When the second parameter of url.parse is true, the query module will be used to analyze the query string. The default is false, so we set it to true
    let data = url. parse(request. url, true);
    let bg = data.query.bg?data.query.bg:'pink';
    console.log(bg);
    //Set the display color of the response result
    response.end(`<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            body {
                background:${<!-- -->bg}
            }
        </style>
    </head>
    <body>
    </body>
    </html>`)
})
//4, listening port
server.listen(8000,()=>{<!-- -->
    console.log('Service is starting....ing');
})

9. Get HTTP request body data

When the requested data comes from a form, you need to get the data in the request body before responding to the service

<form method="post" action="http://127.0.0.1/">
    Username: <input type="text" name="username"/><br/>
    Password: <input type="text" name="userpass"/><br/>
    <button>Login</button>
</form>

About the request body:

  • Most of the request body of the GET request is empty
  • Most of the request body of the POST request is not empty

Three steps to obtain the request body:

1. Declare a string to display the request information

let str = "";

2. Set the binding event and use the readable stream data to read the event

request.on('data',chunk=>{<!-- -->
str + =chunk;
})

3. Binding event, which is triggered when the data is read

request.on('end',()=>{<!-- -->
//Get the result of the request body
console. log(str);
//response result
response.end("over~~~")
)
//1. Import http module
const http = require("http");
//2, create a service
const server = http.createServer((request,response)=>{<!-- -->
    //4, declare a string
    let str = "";
    //5. Binding events
    request.on('data', chunk=>{<!-- -->
        str + =chunk;
    })
    request.on('end',()=>{<!-- -->
        //Get the result of the request body
        console. log(str);
        //response result
        response.end('over~~~')
    })
})
//3, listening port
server.listen(8000,()=>{<!-- -->
    console.log('service starting...');
})

10. HTTP module response related API

  • response.statusCode set response status code
  • response.statusMessage set the response status string (set less)
  • response.setHeader(‘header name’,’header value’) custom header information
  • response.write(‘xx’) set the response body
  • response.end(‘xxx’) set the response body
Two usages of write and end:
//1. Situation 1: Combination of write and end The response body is relatively scattered
response.write('xx');
response.write('xx');
response.write('xx');
...
response.end(); //Each request must have the execution of the end method during processing, which cannot be omitted

//2. Situation 2: Using the end method alone, the response body is relatively concentrated
response.end('xxx');

Case: Build an HTTP service, respond to a table with 4 rows and 3 columns, and realize interlaced color change (JS)

//1. Import http module
const http = require('http');

//2. Create service
const server = http.createServer((request,response)=>{<!-- -->
    response. end(`
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Document</title>
                <style>
                   td{
                       width:100px;
                       height: 50px;
                   }
                   table,td {
                       border-collapse: collapse;
                   }
                </style>
            </head>
            <body>
                <table border="1" align="center" cellpadding="3" cellspacing="3">
                    <tr>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                </table>
                <script>
                   //get all tr rows
                   let trs = document. querySelectorAll('tr');
                   //cycle
                   trs.forEach((item,index)=>{
                        if(index%2==0){
                            item.style.background = "orange";
                        }
                        else {
                            item.style.background = "green";
                        }
                   })
                </script>
            </body>
            </html>
    `)
})

//3. Listen port
server.listen(80,()=>{<!-- -->
    console.log('80 port is starting....ing');
});

Case 2: Build a service and respond to a table with data

const data = [
    {<!-- -->
        id:1,
        name:'Sun Yanzi',
        song:'Backlight'
    },
    {<!-- -->
        id:2,
        name:'Jay Chou',
        song:'unspoken password'
    },
    {<!-- -->
        id: 3,
        name:'JJ Lin',
        song:'A song not for anyone'
    },
    {<!-- -->
        id:4,
        name: 'Mayday',
        song:'Cheers'
    },
    {<!-- -->
        id: 5,
        name: 'Zhang Yixing',
        song: 'Lotus'
    },
    {<!-- -->
        id:6,
        name:'Andy Lau',
        song:'ice rain'
    },
    {<!-- -->
        id: 7,
        name: 'Jacky Cheung',
        song: 'lover'
    }
]

//Requirement: build a form, the data comes from the data variable
require('http').createServer((request,response)=>{<!-- -->
    let body = "";
    body + =`
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Document</title>
                <style>
                   td{
                       width:100px;
                       height: 50px;
                   }
                   table,td{
                       border-collapse: collapse;
                   }
                </style>
            </head>
            <body>
                <table border="1">
                            <tr>
                                <td>id</td>
                                <td>Artist name</td>
                                <td>Famous song</td>
                            </tr>`;
            data.forEach(item=>{<!-- -->
                body + =`
                    <tr>
                        <td>${<!-- -->item.id}</td>
                        <td>${<!-- -->item.name}</td>
                        <td>${<!-- -->item.song}</td>
                    </tr>
                    `
            })

            body + =`
                </table>
            </body>
            </html>
    `;
    response. end(body);
}).listen(80,()=>{<!-- -->
    console.log('Port 80 is running....ing');
})

Regarding the response:

  • Response file content: For files whose HTML content does not change for a long time, use this method
  • Response splicing results: For webpage content, files that often change, use this method
  • At work, the most common case is that the server responds to JSON

11. Fixed implementation of response file content

require('http').createServer((request,response)=>{<!-- -->
    //Get the request method has path
    let {<!-- -->url,method} = request;
    //Judge the request method and request path
    if(method == "GET" & amp; & amp; url == "/index.html"){<!-- -->
        // need to respond to the content of the file
        let data = require('fs').readFileSync(__dirname + '/index.html');
        response. end(data);
    }else if(method == "GET" & amp; & amp; url == "/css/app.css"){<!-- -->
        // need to respond to the content of the file
        let data = require('fs').readFileSync(__dirname + '/public/css/app.css');
        response. end(data);
    }else if(method == "GET" & amp; & amp; url == "/js/app.js"){<!-- -->
        // need to respond to the content of the file
        let data = require('fs').readFileSync(__dirname + '/public/js/app.js');
        response. end(data);
    }
    else{<!-- -->
        //404 response
        response.statusCode = 404;
        response.end("<h1>404 Not Found</h1>");
    }
}).listen(80,()=>{<!-- -->
    console.log('Port 80 is starting....');
})

Obviously, the above code needs to be judged as long as there is a request path. Obviously this method is not perfect, so we need to encapsulate

require('http').createServer((request,response)=>{<!-- -->
    //Get the request method has path
    let {<!-- -->url,method} = request;
    //folder path
    let rootDir = __dirname + '/public';
    // splicing file path
    let filePath = rootDir + url;
    // read file content
    fs.readFile(filePath,(err,data)=>{<!-- -->
        //judge
        if(err){<!-- -->
            //If an error occurs, respond with a 404 status code
            response.statusCode = 404;
            response.end('<h1>404 Not Found</h1>');
        }else{<!-- -->
            //response file content
            response. end(data);
        }
    })
}).listen(80,()=>{<!-- -->
    console.log('Port 80 is starting....');
})

Twelve, the difference between GET and POST requests

GET and POST are two ways of HTTP protocol request.

  • GET is mainly used to obtain data, and POST is mainly used to submit data

  • A GET request with parameters is a GET request after adding parameters to the URL and entering the url in the address bar to access the website.

    POST request with parameters is to put the parameters in the request body

  • POST requests are safer than GET, because the parameters will be exposed in the address bar in the browser

  • GET request size is limited, generally 2K, while POST request has no size limit

  • The GET type message request method is GET, and the POST type message request method is POST

Case 1: For security

? POST is more secure, and GET is less secure

Case 2: Representation

? POST submission data is submitted through the request body

? GET exposes the requested data in the request string in the address bar

Case 3: passing data size

? GET basically transfers data less than 2KB

? There is basically no upper limit on the size of POST (but it can be set through background code (java, php…))

Case 4: Use Scenarios

? GET is usually used to get data

? POST is usually used to submit data

Thirteen, GET and POST usage scenarios

The case of a GET request:

  • Enter url access directly in the address bar
  • click on a link
  • The link tag introduces css
  • The script tag introduces js
  • The img tag introduces pictures
  • The method in the form tag is get
  • get request in ajax

The situation of the post request:

  • The method in the form tag is post
  • ajax post request