前端培训-中级阶段(48)- node 10.x 之 HTTP模块、WEB开发框架介绍


思否
前端培训 HTTP Node.js

转载自 SegmentFault

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

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

HTTP 模块

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

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

  • proxy.headersTimeout 限制解析器等待接收完整 HTTP 请求头的时间。如果不活动,则适用 server.timeout 中定义的规则。 但是,如果请求头发送速度非常慢(默认情况下,每 2 分钟最多一个字节),那么基于不活动的超时仍然允许连接保持打开状态。 为了防止这种情况,每当请求头数据到达时,进行额外的检查,自建立连接以来,没有超过 server.headersTimeout 毫秒。 如果检查失败,则在服务器对象上触发 'timeout' 事件,并且(默认情况下)套接字被销毁。 有关如何自定义超时行为的详细信息,请参见 server.timeout
  • 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开发框架介绍

  • express (我经常用) 基于 Node.js 平台,快速、开放、极简的 Web 开发框架
  • koa 目前有1.x和2.0两个版本。 Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
  • egg Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本。

ThinkJS (公司内部有基于 ThinkJS 的后台) ThinkJS 是一款面向未来开发的 Node.js 框架,整合了大量的项目最佳实践,让企业级开发变得更简单、高效。从 3.0 开始,框架底层基于 Koa 2.x 实现,兼容 Koa 的所有功能。 基于 Koa 2.x,兼容 middleware

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

URL 模块

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

URLSearchParams

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

微信公众号:前端linong

参考文献


原文:SegmentFault

评论

评论功能即将开放。你也可以通过 邮件GitHub Issue 反馈。