NodeJS学习之网络操作

本文介绍如何使用Node.js的http模块创建简单的HTTP服务器及处理HTTP请求和响应,包括数据流的概念、请求与响应的组成,同时介绍了https模块创建HTTPS服务器的方法。

NodeJS -- 网络操作

使用NodeJS内置的http模块简单实现HTTP服务器

var http = require('http');
http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('Hello world\n');
}).listen(8124);

以上程序创建了一个HTTP服务器并监听8124端口,使用http://localhost:8124可以看到效果

:在liunx下监听1024以下的端口号需要root权限

HTTP

'http'模块提供两种使用方式:
1、作为服务端使用时,创建一个HTTP服务器,监听HTTP客户端请求并返回响应
2、作为客户端使用时,发起一个HTTP客户端请求,获取服务端响应
以上的例子就是http模块在服务端模式下的一个简单实现
HTTP请求本质上是一个数据流,由请求头和请求体组成,以下是一个完整的HTTP请求数据内容:
POST / HTTP/1.1
User-Agent: curl/7.26.0
Host: localhost
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlenconded

Hello World

可以看到,空行之上是请求头,之下是请求体。HTTP请求在发送个服务器时,可以认为是按照从头到尾的顺序一个字节一个字节地以数据流方式发送的。而HTTP模块创建的HTTP服务器在接收到完整的请求头后,就会调用回调函数。在回调函数中,除了可以使用request对象访问请求头数据外,还能把request对象当做一个只读数据流来访问请求体数据,例:

http.createServer(function(req, res) {
    var body = [];
    console.log(req.method);
    console.log(req.headers);
    req.on('data', function(chunk) {
        body.push(chunk);
    });
    req.on('end', function() {
        body = Buffer.concat(body);
        console.log(body.toString());
    });
}).listen(80);
----------------------------------
POST
{ 'user-agent': 'curl/7.26.0',
  host: 'localhost',
  accept: '*/*',
  'content-length': '11',
  'content-type': 'application/x-www-form-urlencoded'}
Hello World

HTTP响应本质上也是一个数据流,同样由响应头和响应体组成。例:

HTTP/1.1 200 OK
Content-Type: text/html
Date: Wed, 06 Jul 2016 06:18:17 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Hello World

在回调函数中,除了可以使用response对象来写入响应头数据外,还能把response对象当做一个只写数据流来写入响应体数据,例:服务端原样将客户端请求的请求体数据返回给客户端:

http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    req.on('data', function(chunk) {
        res.write(chunk);
    }
    req.on('end', function() {
        res.end();
    });
}).listen(8080);

由于HTTP请求中的GET请求是最常见的一种,并且不需要请求体,因此http模块也提供了以下便捷API

http.get('http://www.example.com/', function(res) {} );

当客户端发送请求并接收到完整的服务端响应头时,就会调用回调函数,在回调函数中,除了可以使用response对象访问响应头数据外,还能把response对象当作一个只读数据流来访问响应提数据。例:

http.get('http://www.example.com/', function(res) {
    var body = [];
    console.log(res.statusCode);
    console.log(res.headers);
    response.on('data', function(chunk) {
        body.push(chunk);
    });
    res.on('end',function() {
        body = Buffer.concat(body);
        console.log(body.toString());
    });
});
---------------------------------------------
200
{ 'content-type': 'text/html',
  sercer: 'Apache',
  'content-length': '801',
  date: 'Tue, 05 Nov 2013 06:08:41 GMT',
  connection: 'keep-alive' }
<!DOCTYPE html>
...

HTTPS

https模块与http模块极为类似,区别在于https模块需要额外处理SSL证书。
在服务端模式下,创建一个HTTPS服务器,例:
var options = {
    key: fs.readFileSync('./ssl/default.key'),
    cert: fs.readFileSync('./ssl/default.cer')
};

var server = https.createServer(options, function(req, res) {
    // ...
});
与创建HTTP服务器相比,多了一个options对象,通过key和cert字段指定了HTTPS服务器使用的私钥和公钥
另外,NodeJS支持SNI技术,可以根据HTTPS客户端请求使用的域名动态使用不同的证书,因此同一个HTTPS服务器可以使用多个域名提供服务,可以使用以下方法为HTTPS无服务添加多组证书:
server.addContext('foo.com', {
    key: fs.readFileSync('./ssl/foo.com.key'),
    cert: fs.readFileSync('./ssl/foo.com.cer')
});
server.addContext('bar.com', {
    key: fs.readFileSync('./ssl/bar.com.key'),
    cert: fs.readFileSync('./ssl/bar.com.cer')
});

在客户端模式下,发起一个HTTPS客户端请求与http模块几乎相同,例:

var options = {
    hostname: 'www.example.com',
    port: 443,
    path: '/',
    method: 'GET'
};

var req = https.request(options, function(res) {});
req.end();

:目标服务器若使用自制SSL证书,而不是从颁发机构购买,默认情况下https模块会拒绝连接,提示说有证书安全问题。在options里加入rejectUnauthorized: false字段可以禁用对证书有效性的检查,从而允许https模块请求开发环境下使用自制证书的HTTPS服务器

URL

处理HTTP请求时url模块使用率超高,因为该模块允许解析URL、生成URL,以及拼接URL,
URL各组成部分如下所示:

使用.parse方法将一个URL字符串转换为一个URL对象,例:

url.parse('http://user:pass@host.com:8080/p/a/t/h?query=string#hash');
/* =>
{
    protoclo: 'http:',
    auth: 'user:pass',
    host: 'host.com:8080',
    port: '8080',
    hostname: 'host.com',
    hash: '#hash',
    search: '?query=string',
    query: 'query=string',
    pathname: '/p/a/t/h',
    path: '/p/a/t/h?query=string',
    href: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'
}

传给.parse方法的不一定要是一个完整的URL,例如HTTP服务器回调函数中,request.url不包含协议头和域名,但同样可以用.parse方法解析

http.createServer(function (request, response) {
    var tmp = request.url; // => "/foo/bar?a=b"
    url.parse(tmp);
    /* =>
    { protocol: null,
      slashes: null,
      auth: null,
      host: null,
      port: null,
      hostname: null,
      hash: null,
      search: '?a=b',
      query: 'a=b',
      pathname: '/foo/bar',
      path: '/foo/bar?a=b',
      href: '/foo/bar?a=b' }
    */
}).listen(80);
.parse方法还支持第二个和第三个布尔类型的可选参数,第二个参数为true时,该方法返回URL对象中,query字段不再是一个字符串,而是一个经过querystring模块转换后的参数对象,第三个参数等于true时,该方法可以正确解析不带协议头的URL,例如://www.example.com/foo/bar
相反,format方法允许将一个URL对象转换为URL字符串,例:
url.format({
    protocol: 'http:',
    host: 'www.example.com',
    pathname: '/p/a/t/h',
    search: 'query=string'
});
/* =>
'http://www.example.com/p/a/t/h?query=string'
*/

另外,.resolve方法可用于拼接URL,例:

url.resolve('http://www.example.com/foo/bar', '../baz');
/* =>
http://www.example.com/baz
*/

Query String

querystring模块用于实现URL参数字符串与参数对象的互相转换,例:

querystring.parse('foo=bar&baz=qux&baz=quux&corge');
/* =>
{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }
*/

querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' });
/* =>
'foo=bar&baz=qux&baz=quux&corge='
*/

Zlib

zlib模块提供了数据压缩和解压功能,当我们处理HTTP请求和响应时,可能需要用到这个模块

转载于:https://www.cnblogs.com/TwinklingZ/p/5995630.html

### Node.js 学习教程:从入门到精通 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它使开发者能够使用 JavaScript 编写服务器端代码。以下是一个全面的学习路径和资源推荐,帮助你从入门到精通 Node.js。 #### 1. 基础概念 了解 Node.js 的基本概念是学习的第一步。你需要掌握以下内容: - Node.js 的安装与配置[^1] - 全局对象与模块系统[^3] - 异步编程模型及其重要性[^2] ```javascript // 示例:Node.js 中的基本异步操作 const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); }); ``` #### 2. 模块化编程 Node.js 提供了强大的模块化支持,学会如何组织代码是开发中的关键技能。 - CommonJS 模块系统[^1] - ES6 模块的支持与使用[^3] ```javascript // 示例:导出与导入模块 // module.exports 和 exports 的区别 module.exports = { add: function(a, b) { return a + b; } }; // 使用 import 和 export(ES6 模块) export const multiply = (a, b) => a * b; import { multiply } from './math.js'; console.log(multiply(2, 3)); // 输出 6 ``` #### 3. 异步编程 Node.js 的核心特性之一是其非阻塞 I/O 操作,因此熟练掌握异步编程至关重要。 - 回调函数[^2] - Promises - Async/Await ```javascript // 示例:使用 async/await 处理异步操作 async function readFileAsync() { try { const data = await fs.promises.readFile('example.txt', 'utf8'); console.log(data); } catch (err) { console.error(err); } } ``` #### 4. 网络编程 Node.js 提供了丰富的网络编程功能,包括 HTTP 服务器和客户端。 - 创建简单的 HTTP 服务器 - 使用 Express 框架简化开发流程[^1] ```javascript // 示例:使用 Express 创建一个简单的 Web 服务器 const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); ``` #### 5. 数据库操作 Node.js 支持多种数据库,如 MySQL、MongoDB 等。 - 使用 MongoDB 和 Mongoose 进行数据建模[^2] - SQL 数据库连接与查询 ```javascript // 示例:使用 Mongoose 连接 MongoDB const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('Connection error:', err)); ``` #### 6. 实战项目 理论结合实践是最好的学习方式。可以通过以下实战项目加深理解: - 构建 RESTful API - 开发聊天应用 - 构建文件上传服务[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值