Nodejs HTTP Server
背景
最近有一个想法是做一个图片小工具,这个小工具可以给图片提供一些常用或不常用的图片做转换
又一次的 我想到了 cloudflare worker,能白嫖一些计算资源, 可用性又不用担心。(实际上是我想的太美了)。
所以我先想到nodejs上是不是有一些现成的图像处理库,找了一下 还真有 而且API用起来很舒服(Sharp 后续会单开文章来写)。
接下来就需要一个 server 来提供服务,把输入输出都对接好 就完事了。
然而
并不是这么work的。
Cloudflare Worker并不支持Nodejs 只是说恰好支持某些库而已,在这里查找可以在worker上工作的库(实际上我认为就是用了Nodejs但是阉割了非常多的API 防止滥用)
并且 express 也不在支持范围内。虽然给我挖了大坑,但是 探索这件事情本身也非常有意思。
HTTP Module
最开始怎么简单怎么来么,并且我想看看 Nodejs 原生发展的如何
怎么写一个server?
const http = require('http')
// 参数解析
const { URLSearchParams } = require('url');
const port = 8081;
const server = http.createServer()
/**
* server request 事件处理
* @param Request 请求对象可以用来获取客户端的一些请求信息,例如请求路径
* @param Response 响应对象可以用来给客户端发送响应消息
*/
server.on('request', (request, response) => {
console.log('url: ' + request.url)
let body = [];
// https://stackoverflow.com/questions/4295782/how-to-process-post-data-in-node-js
request.on('data', chunk => body.push(chunk))
.on('end',() => {
let buffer = Buffer.concat(body);
// let urlSearchParams = new URLSearchParams(buffer.toString());
console.log(buffer.toString('utf8', 0, 200));
// send response
response.write('resp over.'); // Can be called multiple times
response.end();
})
});
// start server
server.listen(port, () => {
console.log(`server start on http://127.0.0.1:${port}/ `);
})
这里面有一个很有意思的东西, chunk size不固定,且有多次,通过buffer打印出的东西 是这样的
--WebAppBoundary
Content-Disposition: form-data; name="image"; filename="wayne 2022.jpg"
Content-Type: */*; charset=UTF-8
Content-Transfer-Encoding: binary
�����ExifMM*
这是原始未解析的HTTP请求内容。
所以,Spring Web写多了,就非常理所当然的认为 Header,参数的解析都是已经做好的了。
但是,在做应用程序的时候是不能这么原始的来做的。
所以要引入一个web框架,那就是 express
express
const express = require('express')
const multiparty = require('multiparty');
const cors = require('cors')
const app = express()
// test only
app.use(cors({
origin: '*'
}))
// post roter
app.post('/api/image/:type', function (req, res) {
// parse form object
let form = new multiparty.Form();
let image = {
filename: 'untitled.',
size: 0,
buffer: []
};
form.on('close', () => {
let buffer Buffer.concat(image.buffer);
console.log(buffer.toString('utf8', 0, 200));
res.send('requese received');
});
// listen on part event for image file
form.on('part', part => {
part.on('data', (buf) => {
image.size += buf.length;
image.buffer.push(buf);
});
});
// parse the form
form.parse(req);
})
// start server
app.listen(8081)
console.log('Express started on port 8081');
看起来虽然步骤差不多,但是express做了很多解析工作,但有没有做很多。
比如 form表单解析,仍然需要一个multiparty组件去解析,cors虽然默认生效,但无法控制,需要再 引入 cors 组件来控制。
这个工作模式 对我来说 我觉得 真的是尽到了职责分明,不会像是SpringWeb一样全部 All in one 粘合在一起。
当然 他们各有各的好处。
itty-router
itty router 是我必须要介绍,但是又不需要给出 example 的一个组件,因为在我原始的设计中,应用是需要跑在cloudflare上的,所以要用web框架最好的选择就是这个。当然也可以用在其他嵌入式(类似)project中。
具体的例子清参见 cloudflare/worker-template-router