http module for node.js

http module

http protocol : hypertext transfer protocol (one of the most widely used protocols on the Internet)


http request method:

  • get get data
  • post new data
  • put/patch update data
  • deleteDelete data
  • head/options/connect/trace

    URL uniform resource locator, itself is also a string.

Clients and Services

In the network node, the computer responsible for consuming resources is called the client.
The computer responsible for providing network resources to the outside world is called a server.
The http module is a module officially provided by node.js to create a web server. Through the http.createServer() method provided by the http module, an ordinary computer can be easily turned into a web server to provide web resource services to the outside world.

To create a web server using the http module, you need to import it first

const http=require('http')

The difference between a server and an ordinary computer is that web server software is installed on the server, such as IIS, Apache, etc. In Node.js, there is no need to use third-party web server software, and a server can be handwritten with simple code based on the http module provided by Node.js Software that provides web services externally.

Server related concepts

ip address

The ip address is the unique address of each computer on the Internet, and the ip address is unique.

The format of the ip address is usually "dotted decimal", expressed in the form of (a, b, c, d), where a, b, c, and d are all decimal integers between 0 and 255. eg: (192.168.1.1)

Each web server in the Internet has its own ip address. You can run the ping www.baidu.com command on the Windows terminal to check the ip address of the Baidu server.

insert image description here

Domain Names and Name Servers

The ip address is not intuitive and not easy to remember, so there is a character-type address scheme-the domain name address

ip address and the domain name have a one-to-one correspondence, and this correspondence is placed in a computer called a domain name server. Users only need to access the corresponding server through the domain name, and the corresponding conversion work is realized by the domain name server.

Therefore, a domain name server is a server that provides conversion services between IP addresses and domain names.

Note: During development and testing, the domain name corresponding to 127.0.0.1 is localhost , they all represent our own computer, and there is no difference in the use effect.

The port number

A computer can run hundreds of web services, and each web service corresponds to a unique port number. The network request sent by the client can be accurately handed over to the corresponding web service for processing through the port number.

Note:

Each port number cannot be occupied by multiple web services at the same time.

In practical application, port 80 in url can be omitted.

localhost: 80 can directly access localhost

Use of URLs in web pages

URLs can be divided into relative paths and absolute paths

. Relative path: path relative to the current file location.

Absolute path: the real path of the target file on the hard disk (the most accurate path).

The best way to import files from links in html should be absolute path

 <link rel="stylesheet" href="/index.css">

absolute path



The absolute path is highly reliable and relatively easy to understand . https://xxx.com/web is often used in projects to send requests directly to target resources, which is easy to understand. The external link of the website will use this form

//xx.com/web and the protocol splicing of the page URL to test and complete the URL before sending the request. Larger sites use more.
/web and the protocol host name and port of the page are concatenated to form a complete URL before sending the request. Small and medium websites.

relative path

For example, the relative path of http://www.xxx.com/about/h5.html

is calculated with the URL path of the current page when the request is sent, and the request is sent after the complete URL is obtained, which is often used in the learning stage.

Summary of URL Usage Scenarios in Web Pages

Including but not limited to the following scenarios

  • a tag href
  • link tag href
  • script tag href
  • img tag src
  • The src of the video audio tag
  • action in form
  • URL in AJAX request

The browser views the HTTP message

You can use a demo submitted by a form to do related tests

<form action="http://127.0.0.1:9000" method="post">
        <input type="text" name="username">
        <input type="text" name="password">
        <input type="submit" value="提交">
    </form>

Open the corresponding html file in the browser (note that the http server is running before this, and the listening port starts the service), enter the form information to submit, and you can view the network in the F12 console
insert image description here

Get the request line and headers

To get the requested data, you need to pass the request object

  • request.method request method
  • request.httpVersion request version
  • request.url request path
  • require(‘url’).parse(request.url).pathname URL路径
  • require('url').parse(request.url, true).query url query string
  • request.headers request headers
  • request.on(‘data’,function(chunk){});request.on(‘end’,function(){});

Precautions

  • request.url can only get the path and query string, but cannot get the domain name and protocol content in the URL
  • request.headers converts the request information into an object, and converts the attribute names into lowercase.
  • About the path: If you only fill in the ip address or domain name information when visiting the website, the request path at this time is /
  • favicon.ico: request sent automatically by the browser

Create the most basic web server

The basic steps

  1. import http module
const http=require('http')
  1. Create a web server instance
    Call the http.createServer() method to quickly create a web server instance
    const server=http.createServer()
  1. Bind the request event to the server instance and listen to client requests
    // 使用服务器实例的.on()方法,为服务器绑定一个request事件
    server.on('request', (req, res) => {
        // 只要有客户端来请求我们自己的服务器,就会触发request事件,从而调用这个事件处理函数
        console.log('Hello HTTP Server')
    })

req is an object that encapsulates the request message, and can obtain the relevant content of the request message.
res is an object that encapsulates the response message, and can obtain the relevant content of the response message

  1. Start the server
    Call the .listen() method of the server to start the current web server instance
// 调用服务器实例的.listen(端口号,cb回调)方法,即可启动当前的web服务器实例
server.listen(9000, () => {
    console.log('服务已经启动')
})

The node command can be executed in powdershell, and
the new terminal of vscode terminal can also execute the node command, ctrl+c suspends the server
insert image description here

Precautions

  • Command line ctrl+c to stop the service
  • When the service is started, the update code must restart the service to take effect
  • The solution to the Chinese garbled characters in the response content
response.setHeader('Content-type', 'text/html;charset=utf-8');
  • The port number is occupied
    Error: listen EADDRINUSE: address already in use :::9000
    (1) Close the service currently running on the listening port
    (2) Modify other port numbers

  • The default port of the HTTP protocol is 80, and the commonly used ports for HTTP service development are 3000, 8080, 8090, 9000, etc.
    If the port is occupied by other programs, you can use the resource monitor to find the program that occupies the port, and then use the task manager to close the corresponding program.
    Right-click Task Manager on the taskbar at the bottom of the desktop, click Performance, and there will be Resource Monitor at the bottom of the window
    insert image description here
    insert image description here

    Find the pid of the process occupying the port according to the resource monitor, find the process according to the pid in the resource manager, right-click to end the task, and the port can be used. In addition, if the pid does not display the pid, right-click on the name and select the pid to display it as shown in the figure
    insert image description here

  • HTTPS protocol default port is 443

req request object

As long as the server receives the client's request, it will call the request event handler bound to the server through server.on(). If you want to access client-related data or properties

in an event handler , you can use the following method:

server.on('request', (req) => {
    //req是请求对象,它包含了与客户端相关的数据和属性,例如:
    // req.url是客户端请求的URL地址
    // req.method是客户端的method请求类型
    const str = 'Your request url is ${req.url}, and request method is ${req.method}'
    console.log(str)
})

The complete code that runs is as follows

const http = require('http')

const server = http.createServer()

server.on('request', (req) => {
    //req是请求对象,它包含了与客户端相关的数据和属性,例如:
    // req.url是客户端请求的URL地址
    // req.method是客户端的method请求类型
    const str = 'Your request url is ${req.url}, and request method is ${req.method}'
    console.log(str)
})

// 调用服务器实例的.listen(端口号,cb回调)方法,即可启动当前的web服务器实例
server.listen(1314, () => {
    console.log('http server running at http://127.0.0.1')
})

Running port 80 reports an error
insert image description here

So it was changed to port 1314
and the operation was successful.insert image description here

res response object

In the server's request event handler, if you want to access server-related data or attributes, you can use the following methods:

server.on('request', (req, res) => {
    // res是响应对象,它包含了与服务器相关的数据和属性,例如 要发送到客户端的字符串
    const str = 'Your request url is ${req.url}, and request method is ${req.method}'
    // res.end()方法向客户端发送指定内容,并结束这次请求的处理过程
    res.end(str)
})

complete running code

// 导入http模块
const http = require('http')
// 创建web服务器实例
const server = http.createServer()
// req是请求对象,包含与客户端相关的数据和属性
server.on('request', (req,res) => {
    // req.url事故客户端请求的url地址
    const url = req.url
    // req.method是客户端请求的method类型
    const method = req.method
    const str = 'Your request url is ${url}, and request method is ${method}'
    console.log(str)

    // 调用res.end()方法,向客户端响应一些内容
    res.end(str)
})
server.listen(1314, () => {
    console.log('server running at http://127.0.0.1')
})

Screenshot of running results
insert image description here

Code example for creating HTTP message and extracting request body

const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
// 获取请求的方法
    console.log(request.method);
    // 获取请求的url
    console.log(request.url);//只包含url中的路径与查询字符串
    // 获取HTTP协议的版本号
    console.log(request.httpVersion)
    // 获取HTTP的请求头
    console.log(request.headers.host);
    response.end('http');//设置响应体
});
// 监听端口,启动服务
server.listen(9000, () => {
    console.log('服务已经启动')
});

Enter the request in the address bar
insert image description here

request.url will output the url path and query string on the terminal
insert image description here

Extract the request body of the HTTP message

const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
// 声明一个变量
    let body = '';
    // 绑定data事件
    request.on('data', chunk => {
        body += chunk;
    })
    // 绑定end事件
    request.on('end', () => {
        console.log(body);
        // 响应
        response.end('Hello HTTP');
    });
});
// 监听端口,启动服务
server.listen(9000, () => {
    console.log('服务已经启动')
});

insert image description here

Sending the request directly in the address bar is a get request, the request body is empty, and the server returns empty
insert image description here

You can send non-empty requests with the help of html forms

Extract the path and query string of the URL in the HTTP message

const http = require('http');
const url = require('url');
const server = http.createServer((request, response) => {
    let res = url.parse(request.url, true);
    console.log(res);
    let pathname = res.pathname;
    let keyword = res.query.keyword;
    console.log(keyword);
    response.end('url');
});
// 监听端口,启动服务
server.listen(9000, () => {
    console.log('服务已经启动')
});

At the beginning, there was no listening port to start the service. I wondered why there was no response after the node command, which is funny. . .
insert image description here

There is another way, the code is as follows

const http = require('http');
const { URL } = require('url');
const server = http.createServer((request, response) => {
    // 实例化url的对象
    // let url = new URL('http://www.xxx.com/search?a=100&b=200');
    // let url = new URL('./search?a=100&b=200', 'http://127.0.0.1:9000');
        let url = new URL(request.url, 'http://127.0.0.1:9000');
//    输出路径
    console.log(url.pathname);
    // 输出keycode查询字符串
    console.log(url.searchParams.get('keyword'));
    response.end('url new');
});
server.listen(9000, () => {
    console.log('服务已经启动')
});

Note the code that instantiates the url object.

HTTP request practice questions

Build an HTTP service according to the following requirements
. The request type is get, and the request address is /login and /reg. The response body results are the login page and the registration page respectively.

core steps

  • Get the requested url address
  • Set the default corresponding content to 404 Not found
  • Determine whether the user requested /login.html
  • Determine whether the user requested /reg.html
  • Set the Content-Type response header to prevent Chinese garbled characters
  • Use res.end() to respond the content to the client

The basic code template is as follows

// 1.导入http模块
const http = require('http');
// 2.创建服务对象
const server = http.createServer((request, Response) => {
    Response.end('practise');
});
// 3.监听端口,启动服务
server.listen(9000, () => {
    console.log('服务已经启动,,端口9000监听中')
})

The code template based on the above code, because the callback function will be executed when there is a request, so the function function will be placed in the callback function, and it is necessary to judge the request method and whether the url path matches the requirement.
Since there can only be one end method in the end, the original practice end method should be deleted after writing the judged end method. Otherwise, an error message of write after end will appear.
After deleting, the content of the running page appears Chinese garbled characters. At this time, you only need to set response.setHeader.

let method=request.method;
can be abbreviated as
let { method } = request;
there is a method attribute in request, so it can be obtained by assignment. [Object deconstruction]

The complete code is as follows, the last else guarantees the response of Google browser favicon.ico

// 1.导入http模块
const http = require('http');
// 2.创建服务对象
const server = http.createServer((request, Response) => {
    // 获取请求的方法
    let { method } = request;
    // 获取请求的url路径
    let { pathname } = request;
    // let pathname = new URL(request.url, 'http://127.0.0.1');
    Response.setHeader('content-type', 'text/html;charset=utf-8');
    // console.log(pathname);
    // console.log(method);
    // 判断
    if (method === 'GET' && require('url').parse(request.url).pathname  === '/login') {
        // 登录的情形
        Response.end('登录页面');
    } else if (method === 'GET' && require('url').parse(request.url).pathname  === '/reg') {
        Response.end('注册页面');
    } else {
        Response.end('404 Not Found');
    }
    
});
// 3.监听端口,启动服务
server.listen(9000, () => {
    console.log('服务已经启动,,端口9000监听中')
})

【bug record】

The judgment logic is as follows. Before the judgment, pathname and method are printed. The former is a url collection and the latter is get. The login and reg pages cannot be switched normally. The page only displays the default style of 404 not found anyway.
Finally, the pathname was replaced with require('url').parse(request.url).pathname, and the page switching was normal. Or use the object destructuring statement above let { pathname } = request;

//存在问题的代码示例
    if (method === 'GET' && pathname  === '/login') {
        // 登录的情形
        Response.end('登录页面');
    } else if (method === 'GET' && pathname  === '/reg') {
        Response.end('注册页面');
    } else {
        Response.end('404 Not Found');
    }

Set HTTP response message

  • Set response status code response.statusCode
  • Set the response status description response.statusMessage (very rarely used)
  • Set the response header information response.setHeader('header name','header value')
  • Set the response body response.write('xx') or response.end('xxx')

Set the response status code Response.statusCode = 203 in the service object
;
the default response status code is 200, and the setting after multiple settings will overwrite the previous hahaha.

Set the response status description in the service object
Response.statusMessage = 'sorry tony';

insert image description here

Set the response header in the service object

  • Response.setHeader(‘content-type’, ‘text/html;charset=utf-8’);
  • Response.setHeader(‘server’, ‘node.js’);
  • // Response.setHeader('Signal', 'Who is waiting for dawn');//error
  • Response.setHeader(‘test’, [‘a’, ‘b’, ‘c’]);

    insert image description here

Setting the Chinese content in the response header will give an error
insert image description here

Response body settings

  • Response.write(‘love’);
  • Response.write(‘love’);
  • Response.write(‘love’);
  • Response.write(‘love’);
  • Response.end();//Set the response body

The response body can be set repeatedly, and finally it will be overlaid and presented on the page. Generally, the carrier is set in write, but the carrier will not be set in end.
insert image description here

HTTP Response Exercises

Build an HTTP service, respond to a table with 4 columns and 3 rows, and require the table to have an interlaced color change effect, and click on the cell to highlight it


const http = require('http');
const fs = require('fs');

const server = http.createServer((request, Response) => {
    // 读取文件内容
    let html = fs.readFileSync(__dirname + '/http响应表格.html');
    Response.end(html);//end可以是字符串可以是buffer
});

server.listen(9000, () => {
    console.log('服务已经启动,,端口9000监听中')
})

The html part is as follows

<!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>
</head>
<style>
    td {
        padding: 20px 40px;

    }

    table tr:nth-child(odd) {
        background: #aef;
    }

    table tr:nth-child(even) {
        background: #fcb;
    }

    table,
    td {
        border-collapse: collapse;
    }
</style>
<script>
    // 获取所有的td
    let tds = document.querySelectorAll('td');
    // 遍历
    tds.forEach(item => {
        item.onclick = function () {
            this.style.background = '#red';
        }
    })
</script>
<body>
    <table border="1">
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </table>
</body>
</html>

The problem in the previous few runs is that the function executed by the js part of the code is to click the corresponding table to display the cursor instead of highlighting it. I don’t know where the problem is for the time being.
The next day, I laughed, and the code in the script tag was written into window.οnlοad=function(){}, it would be fine hahaha.

The basic process of loading web resources

html

<head>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
        <h1>测试</h1>
        <hr>
        <img src="./素材/msld1.jpg">
        <script src="./index.js"></script>
</body>

css


body{
    height: 100vh;
    padding: 20px;
    box-sizing: border-box;
    background: linear-gradient(right  bottom,#aef,#c90);
}
hr{
    margin: 20px 0;
    border-bottom: solid 1px rgba(0, 0, 0, 0.363);
}

js

window.onload = function () {
    let img = document.querySelector('img');
    img.onclick = function () {
        alert('点我干嘛')
    }
}

[Record bug] insert image description here


Consider adding an else condition to judge and return img insert image description here
, but it is still not possible

to move the image resource to the English folder, and it still does not display.

Finally, the normal display of the file is to right-click open with live server in the html file of vscode, and it will be displayed normally under port 5500.

Static resource service

Static resources refer to resources whose content does not change for a long time, such as pictures and videos, script files, font files, html files, etc.

Dynamic resources are resources whose content is frequently updated, such as Baidu homepage, Netease homepage, Jingdong search list page, etc. .

const http = require('http');
const fs = require('fs');

// 创建服务对象
const server = http.createServer((req, res) => {
    // 获取请求url的路径
    let { pathname } = new URL(req.url, 'http://127.0.0.1');
    // 拼接文件路径
    let filePath = __dirname + '/page' + pathname;
    // 读取文件fs异步API
    fs.readFile(filePath, (err, data) => {
        if (err) {
            Response.statusCode = 500;
            Response.end('文件读取失败');
            return;//防止代码继续往后执行
        }
        // 响应文件内容
        Response.end(data);//设置响应体
    })
});
server.listen(9000, () => {
    console.log('服务已经启动')
});

Static resource directory and website root directory

In which folder does the http service look for static resources? That folder is the static resource directory, also known as the website root directory.

When using live-server to access HTML in vscode, who is the root directory of the service website that it starts

? folder

const http = require('http');
const fs = require('fs');

// 创建服务对象
const server = http.createServer((req, res) => {
    // 获取请求url的路径
    let { pathname } = new URL(req.url, 'http://127.0.0.1');
    // 声明一个变量
    let root = __dirname + '/../';
    // 拼接文件路径
    let filePath = root + pathname;
    // 读取文件fs异步API
    fs.readFile(filePath, (err, data) => {
        if (err) {
            res.setHeader('content-type', 'text/html;charset=utf-8');
            res.statusCode = 500;
            res.end('文件读取失败');
            return;//防止代码继续往后执行
        }
        // 响应文件内容
        Response.end(data);//设置响应体
    })
});
server.listen(9000, () => {
    console.log('服务已经启动')
});

operation resultinsert image description here

Set resource type mime

A media type (MIME type) is a standard used to represent the nature and format of a document, file, or byte stream.

The HTTP service can set the response header Content-Type to indicate the MIME type of the response body, and the browser will decide how to process the resource based on the type.

mime types corresponding to common files

  • application/octet-stream
    This is the default for application files. For unknown application files, browsers generally do not automatically execute or ask for execution.
  • text/plain
    Text file default. Even if it means an unknown text file, the browser thinks it can be displayed directly.
    text/css
    text/html
    text/javascript
    For unknown resource types, you can choose the application/octet-stream type. When the browser encounters this type of response, it will store the content of the response body independently, which is our common download Effect.
const http = require('http');
const fs = require('fs');
const path = require('path');

// 创建服务对象
const server = http.createServer((req, res) => {
    // 获取请求url的路径
    let { pathname } = new URL(req.url, 'http://127.0.0.1');
    // 声明一个变量
    // let root = __dirname + '/../';
    let root=__dirname
    // 拼接文件路径
    let filePath = root + pathname;
    // 读取文件fs异步API
    fs.readFile(filePath, (err, data) => {
        if (err) {
            res.setHeader('content-type', 'text/html;charset=utf-8');
            res.statusCode = 500;
            res.end('文件读取失败');
            return;//防止代码继续往后执行
        }
        // 获取文件的后缀名
        let ext = path.extname(filePath);
        console.log(ext);
        res.setHeader('content-type','xxx')
        // 响应文件内容
        res.end(data);//设置响应体
    })
});
server.listen(9000, () => {
    console.log('服务已经启动')
});

Screenshot of running results
insert image description here

insert image description here

// 声明一个变量
let mimes = {
    html: 'text/html',
    css: 'text/css',
    js: 'text/javascript',
    png: 'image/png',
    jpg:'image/jpeg'
}
let type = mimes[ext];
        if (type) {
            // 匹配到
            res.setHeader('content-type', type);
        } else {
            // 没有匹配到
            res.setHeader('content-type', 'application/octet-stream');
        }

insert image description here
insert image description here
insert image description here

If there is Chinese in the css resource (Chinese comments are also counted), then the page will also appear garbled when accessing specific files, and html will not be garbled because the meta setting character is utf-8. Of course, the charset priority of the response header is higher. Some
insert image description here
insert image description here

Improve error handling

Open a file that does not exist and report an error, improve error handling

if (err) {
            // 设置字符集
            res.setHeader('content-type',' text/html; charset=utf-8');
               // 判断错误的代号
            switch (err.code) {
                case 'ENOENT':
                    res.statusCode = 404;
                    res.end('<h1>404 Not Found </h1>');
                case 'EPERM':
                           res.statusCode = 403;
                    res.end('<h1>403 Forbidden </h1>');
            }
            return;
        }

The first err accesses a file that does not exist, and the second err manually modifies the permissions of the html read attribute, prohibits reading, and then tests. You can operate it in the right-click attribute security editor.
insert image description here
insert image description here

Error handling of the third request method

You can use the form form to make a post request, open the form to submit the form to send the post request

insert image description here
The fifth other error handling

 	default:
                  res.statusCode=500;
                  res.end('<h1>500 Internal Server Error </h1>');

GET and POST usage scenarios

The scene of the get request

  • Enter url access directly in the address bar
  • click on a link
  • The link tag introduces css
  • The script tag introduces js
  • video and audio introduce multimedia
  • The img tag introduces pictures
  • The method in the form tag is get (case insensitive)

  • Scenario of get request post request in ajax
  • The method in the form tag is post (case insensitive)
  • post request in AJAX

The difference between get and post requests

get and post are two ways of http protocol request, the main differences are as follows

  1. Function, get is mainly used to obtain data, post is mainly used to submit data
  2. parameter position. A get request with parameters is to add parameters to the URL, and a post with parameters is to put the parameters in the request body.
  3. safety. post request is safer than get, because the parameters will be exposed in the address bar in the browser
  4. The size of the get request is limited, generally 2k, while the size of the post request is not limited.

Guess you like

Origin blog.csdn.net/weixin_55355282/article/details/131136237