4

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

HTTP模块、WEB开发框架介绍、URL & querystring

HTTP 模块

nodejs 中分为 HTTP、HTTPS、HTTP2 三个模块,是不是头秃。

  1. const http = require('http');,作为普通 http/1 的API。
    Node.js 中的 HTTP 接口旨在支持许多传统上难以使用的协议的特性。
    特别是,大块的(且可能是块编码的)消息。
    接口永远不会缓冲整个请求或响应,所以用户可以流式地传输数据。
    可以用来作为 HTTP 服务器或者客户端。
  2. const http2 = require('http2');, 核心 API 提供了专门针对支持 HTTP/2 协议的特性而设计的底层接口。 它不是专门设计为与现有的 HTTP/1 模块 API 兼容。 当然,也有兼容的 API
  3. const https = require('https');, HTTPS 是基于 TLS/SSL 的 HTTP 协议。在 Node.js 中,其被实现为一个单独的模块。

当客户端使用

讲道理我一般是用 axios 来使用,

// 请求服务端
http.get('http://www.lilnong.top/cors/node-http')
    .on('response', (res /** http.IncomingMessage */)=>{
        res.on('data', (buffer)=>{
            // 这里应该把 buffer 拼接一下的,不应该直接用
            console.log('data', buffer.toString())
        })
    })

对应 axios 我们可以写的更加简单

axios('http://www.lilnong.top/cors/node-axios')
    .then(v=>v.data)
    .then(data=>console.log(data))

由于大多数请求都是不带请求体的 GET 请求,因此 Node.js 提供了这个便捷的方法。 这个方法与 http.request() 唯一的区别是,它将请求方法设置为 GET 并且会自动调用 req.end()。 由于 http.ClientRequest 章节中所述的原因,回调必须要消费响应的数据。

当服务端使用

// 启动服务器
const proxy = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain;charset=utf8' });
    res.end('响应内容');
});
// 监听对应的端口
proxy.listen(1337, '127.0.0.1',(...args)=>{
    console.log('listen', args)
})

我一般是用 express 来起服务。

  1. proxy.headersTimeout 限制解析器等待接收完整 HTTP 请求头的时间。如果不活动,则适用 server.timeout 中定义的规则。 但是,如果请求头发送速度非常慢(默认情况下,每 2 分钟最多一个字节),那么基于不活动的超时仍然允许连接保持打开状态。 为了防止这种情况,每当请求头数据到达时,进行额外的检查,自建立连接以来,没有超过 server.headersTimeout 毫秒。 如果检查失败,则在服务器对象上触发 'timeout' 事件,并且(默认情况下)套接字被销毁。 有关如何自定义超时行为的详细信息,请参见 server.timeout
  2. proxy.timeout 认定套接字超时的不活动毫秒数。值为 0 将禁用传入连接的超时行为。套接字超时逻辑在连接时设置,因此更改此值仅影响到服务器的新连接,而不影响任何现有连接。

http2 模块

核心 API 提供了专门针对支持 HTTP/2 协议的特性而设计的底层接口。 它不是专门设计为与现有的 HTTP/1 模块 API 兼容。 当然,也有兼容的 API

http2 核心 API 在客户端和服务器之间比 http API 更加对称。 例如,大多数事件,比如 'error''connect''stream',都可以由客户端代码或服务器端代码触发。

当服务端使用

http://nodejs.cn/api/http2.html#http2_client_side_example

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

// 由于没有已知的浏览器支持[未加密的 HTTP/2](http://nodejs.cn/s/yfVdqh),
// 因此在与浏览器客户端进行通信时必须使用 [`http2.createSecureServer()`](http://nodejs.cn/s/zQgH8T)。
const server = http2.createSecureServer({
  key: fs.readFileSync('密钥.pem'),
  cert: fs.readFileSync('证书.pem')
});
server.on('error', (err) => console.error(err));

server.on('stream', (stream, headers) => {
  // 流是一个双工流。
  stream.respond({
    'content-type': 'text/html; charset=utf-8',
    ':status': 200
  });
  stream.end('<h1>你好世界</h1>');
});

server.listen(8443);

要生成此示例的证书和密钥,可以运行:

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' 
  -keyout 密钥.pem -out 证书.pem

客户端实例

http://nodejs.cn/api/http2.html#http2_client_side_example

const http2 = require('http2');
const fs = require('fs');
const client = http2.connect('https://localhost:8443', {
  ca: fs.readFileSync('证书.pem')
});
client.on('error', (err) => console.error(err));

const req = client.request({ ':path': '/' });

req.on('response', (headers, flags) => {
  for (const name in headers) {
    console.log(`${name}: ${headers[name]}`);
  }
});

req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
  console.log(`n${data}`);
  client.close();
});
req.end();

https 模块

一般我都是 nginx 支持https,proxy_pass 到 http 的。http://nodejs.cn/api/https.html#https_https

当服务端使用

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

const options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('你好,世界n');
}).listen(8000);

或者

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

const options = {
  pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
  passphrase: '密码'
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('你好,世界n');
}).listen(8000);

当客户端使用

const https = require('https');

https.get('https://encrypted.google.com/', (res) => {
  console.log('状态码:', res.statusCode);
  console.log('请求头:', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });

}).on('error', (e) => {
  console.error(e);
});

WEB开发框架介绍

  1. express (我经常用)
    基于 Node.js 平台,快速、开放、极简的 Web 开发框架
  2. koa 目前有1.x和2.0两个版本。
    Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
  3. egg
    Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本。
  4. ThinkJS (公司内部有基于 ThinkJS 的后台)
    ThinkJS 是一款面向未来开发的 Node.js 框架,整合了大量的项目最佳实践,让企业级开发变得更简单、高效。从 3.0 开始,框架底层基于 Koa 2.x 实现,兼容 Koa 的所有功能。

    • 基于 Koa 2.x,兼容 middleware
    • 内核小巧,支持 Extend、Adapter 等插件方式
    • 性能优异,单元测试覆盖程度高
    • 内置自动编译、自动更新机制,方便快速开发
    • 使用更优雅的 async/await 处理异步问题,不再支持 */yield
    • 从 3.2 开始支持 TypeScript
  5. nest、sails、loopback、fastify、hapi、pomelo 等等

URL 模块

用于处理与解析 URL。 可以获取查询字符串、协议、hostname、锚点等等

image.png

URLSearchParams

提供对查询字符串(querystring、params、searchparams)处理,也可以使用 qs 库处理
image.png

微信公众号:前端linong

clipboard.png

参考文献

  1. 前端培训目录、前端培训规划、前端培训计划
  2. https://zhuanlan.zhihu.com/p/87079561

linong
29.2k 声望9.5k 粉丝

Read-Search-Ask