首页 前端知识 使用 nodejs 中的 http 模块实现几个超实用的工具,html5移动web开发实战

使用 nodejs 中的 http 模块实现几个超实用的工具,html5移动web开发实战

2024-05-29 10:05:03 前端知识 前端哥 735 694 我要收藏

在做开发和调试过程中,经常需要考虑到一个请求或者图片等加载很慢时,应该怎么处理。

比如有用户反馈某些图片加载很慢,导致页面看起来不正常。那么我就应该针对图片加载慢进行一些处理,可是怎么模拟这个加载很慢的图片呢?

很多现有的接口,都无法模拟出这种有特殊延迟的情况,这里我们可以使用 http 模块来实现。

我们在第 1 个 http 服务器的基础上,进行改进。

res.end()方法会告知服务器当前次响应结束,若没有调用,则一直处于等待状态。

我们要实现一个有延迟的响应,可以使用 setTimeout 延迟调用 end()方法即可。这里先实现一个有延迟的接口。

http

.createServer((req, res) => {

const index = req.url.indexOf(‘?’);

if (index >= 0) {

const query = req.url.slice(index);

const ss = new URLSearchParams(query);

const timeout = ss.get(‘timeout’);

const type = ss.get(‘type’);

if (timeout && Number(timeout)) {

return setTimeout(() => {

if (type === ‘json’) {

res.writeHead(200, { ‘Content-Type’: ‘application/json’ });

res.end(JSON.stringify({ code: 0, msg: ‘hello world’ }));

} else if (type === ‘image’) {

// 输出本地一个图片

} else {

res.end(delay ${timeout}ms response);

}

}, Number(timeout));

}

}

res.end(‘hello world!’);

})

.listen(port, ip);

想要延迟输出图片时,需要通过数据流的方式读取本地的图片,然后输出到前端:

const stream = fs.createReadStream(‘./img/s.jpg’);

const responseData = []; //存储文件流

if (stream) {

//判断状态

stream.on(‘data’, function (chunk) {

responseData.push(chunk);

});

stream.on(‘end’, function () {

const finalData = Buffer.concat(responseData);

// response.write();

res.writeHead(200, { ‘Content-Type’: ‘image/jpg’ });

res.end(finalData);

});

}

3. 实现接口的中转代理


我们有时会遇到需要的接口存在跨域,或者是内网接口的问题,这时我们就需要通过一个中间层,来对接口进行中转代理,才能正常地访问接口。

无所谓,也有点累

3.1 原生 http 模块来实现

实现接口代理时要注意亮点:

  1. 透传,接收到的所有数据,根据需要尽量都传给代理的接口,例如 cookie,参数等;

  2. 设置跨域头,为了方便前端的访问,我们需要在返回的头部加上 3 个可以跨域的字段;

跨域的方式有很多种,比如 jsonp 也是其中一种,但 cors 跨域是比较好的一种,前端可以有效地控制请求时间和取消请求。

在设置跨域头Access-Control-Allow-Origin时,这里是不建议直接设置成*。一方面是不安全,所有的域名都可以访问;再有就是前端不会再传送 cookie,无法进行一些登录态的校验等。

在设置Access-Control-Allow-Origin之前,我们要先校验下 headers 中的 referer,如果为空或者不满足白名单的要求,则可以直接返回 403。

const allowList = [‘joke.qq.com’, ‘www.qq.com’];

if (!req.headers || !req.headers.referer) {

res.writeHead(403, ‘forbidden’);

res.end(‘403 forbidden’);

return;

}

const { hostname } = new URL(req.headers.referer);

if (!allowList.includes(hostname)) {

res.writeHead(403, ‘forbidden’);

res.end(‘403 forbidden’);

return;

}

满足要求之后,需要将 referer 最后的斜杠/去掉,否则会设置不成功。完成的代码样例如下:

const http = require(‘http’);

const https = require(‘https’);

const ip = process.env.IP || ‘127.0.0.1’;

const port = process.env.PORT || 3001;

http

.createServer((req, res) => {

const allowList = [‘joke.qq.com’, ‘www.qq.com’];

if (!req.headers || !req.headers.referer || allow) {

res.writeHead(403, ‘forbidden’);

res.end(‘403 forbidden’);

return;

}

console.log(‘发起请求’, req.headers);

https

.get(‘https://www.v2ex.com/api/topics/latest.json’, (response) => {

let data = ‘’;

response.on(‘data’, (chunk) => {

data += chunk;

});

response.on(‘end’, () => {

res.setHeader(‘Access-Control-Allow-Origin’, (req.headers.referer || ‘’).replace(//$/, ‘’));

res.setHeader(‘Access-Control-Allow-Methods’, ‘GET, POST’);

res.setHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With,content-type’);

res.end(data);

});

})

.on(‘error’, (e) => {

console.error(请求遇到问题: ${e.message}, e);

res.end(‘error’);

});

})

.listen(port, ip);

console.log(server has started at ${ip}:${port});

3.2 proxy 代理组件

若需要代理更多的接口,或者路径是从前端传过来的,我们自己倒是也可以实现,不过还有更方便的 proxy 代理组件了。

我养你

这里我们用 http-proxy 组件来实现:

const http = require(‘http’);

const httpProxy = require(‘http-proxy’);

const ip = process.env.IP || ‘127.0.0.1’;

const port = process.env.PORT || 3000;

const proxy = httpProxy.createProxyServer({

target: ‘https://www.v2ex.com’, // 代理的接口地址

changeOrigin: true,

});

http

.createServer((req, res) => {

// 设置跨域头

res.setHeader(‘Access-Control-Allow-Origin’, (req.headers.referer || ‘’).replace(//$/, ‘’));

res.setHeader(‘Access-Control-Allow-Methods’, ‘GET, POST’);

res.setHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With,content-type’);

// 将请求和响应的对象传给proxy

proxy.web(req, res);

})

.listen(port, ip);

然后前端直接按照路径发起请求即可:

axios(‘http://localhost:3000/api/topics/latest.json’).then(console.log).catch(console.error);

4. 模拟数据


前端在写页面逻辑时,经常要考虑到数据的各种情况,比如无数据时,长列表,各种长度的昵称等。

头脑发热

无论是读取配置的 json 文件,还是用代码生成的数据,都不具有随机性。

现在,我们可以利用 mockjs 来实现各种数据的模拟:

const http = require(‘http’);

const Mock = require(‘mockjs’);

const ip = process.env.IP || ‘127.0.0.1’;

const port = process.env.PORT || 3000;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

分享一套阿里大牛整理的前端资料给大家,点击前端校招面试题精编解析大全即可免费下载

❤️ 谢谢支持,喜欢的话别忘了 关注、点赞哦。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-OUEw3ePT-1712294592925)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

分享一套阿里大牛整理的前端资料给大家,点击前端校招面试题精编解析大全即可免费下载

❤️ 谢谢支持,喜欢的话别忘了 关注、点赞哦。

前端校招面试题精编解析大全

转载请注明出处或者链接地址:https://www.qianduange.cn//article/9986.html
标签
okhttp
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!