写点什么

使用 nodejs 中的 http 模块实现几个超实用的工具,实战 java 虚拟机葛一鸣第二版 pdf

用户头像
极客good
关注
发布于: 刚刚

});


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. 模拟数据




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


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


表,各种长度的昵称等。



无论是读取配置的 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;


http


.createServer((req, res) => {


const result = Mock.mock({


code: 0,


msg: 'success',


'x-from': 'mock',


data: Mock.mock({


'rank|20': [


{


'no|+1': 1, // no 字段从 1 开始自增


uin: () => Mock.Random.string(32), // 32 长度的随机字符串


nick: () => Mock.Random.string(1, 20), // 长度在 1-20 之间的随机字符串


face: () => Mock.Random.image('120x120'), // 120*120 的图片


score: () => Mock.Random.integer(1, 2000), // 分数


},


],


}),


});


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.writeHead(200, { 'Content-Type': 'application/json' });


res.end(JSON.stringify(result, null, 2));


})


.listen(port, ip);


生成的数据:



用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
使用 nodejs 中的 http 模块实现几个超实用的工具,实战java虚拟机葛一鸣第二版pdf