一、简介,用nodejs实现简单的http代理案例
步骤1:新建文件夹、在当前路径打开命令行输入 npm init 回车初始化项目,然后就有了 package.json 文件
步骤2:安装express,搭建简易服务器
安装express:npm i express -S
安装完成后,新建 index.js 文件,代码如下:
const express = require('express'); const app = express(); const port = 3000; //端口号 //监听请求 *代表所有的请求路径。 //也可指定请求路径,如/text,则只能接收http://localhost:3000/text的请求 app.get('*', (req, res) => { res.send('Hello World!'); }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
然后命令行执行 node index.js, 看到打印 Example app listening at http://localhost:3000,就说明服务已经跑起来了
在浏览器访问 http://localhost:3000,看到 Hello World!,说明运行的服务收到请求并且正常返回结果了
步骤3:使用request模块转发http请求,得到结果并返回
安装request:npm i request -S
const express = require('express'); const app = express(); const port = 3000; //端口号 const request = require('request'); //监听请求 *代表所有的请求路径。 //也可指定请求路径,如/text,则只能接收http://localhost:3000/text的请求 app.get('*', (req, res) => { //接收要转发的http地址 let url = req.url.substr(1); if(url.startsWith('http')){ const options = { url, method:"GET", //headers: req.headers //如果需要设置请求头,就加上 } request(options, function (error, response, body) { if (!error && response.statusCode === 200) { //拿到实际请求返回的响应头,根据具体需求来设置给原来的响应头 let headers = response.headers; res.setHeader('content-type',headers['content-type']); res.send(body); } else { res.send(options); } }); } }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
在命令行重新运行 index.js,ctrl + c 终止运行再 node index.js 。
然后在浏览器访问 http://localhost:3000/https://www.baidu.com/,看到 百度搜索的界面,说明代理请求成功了
到了这里,相信读者应该可以看出具体用法了,http://localhost:3000/https://www.baidu.com/,后面红色部分就是具体要转发的请求
需要注意的是,这个代码是用来代理ajax请求的,像上面的例子请求的是百度的界面,这个是为了测试,有些网页可能无法打开。
还有就是,需要根据你的实际情况来修改,比如你请求的接口需要修改请求头如content-type之类的
步骤4:代理post请求
前面只实现了get请求代理,要代理post请求还需要安装一个模块(body-parser)来获取请求体
安装body-parser: npm i body-parser -S
const express = require('express'); const app = express(); const port = 3000; //端口号 const request = require('request'); var bodyParser = require('body-parser') //只要加入这个配置,在req请求对象上会多出来一个属性 //parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) //parse application/json app.use(bodyParser.json()) //监听请求 *代表所有的请求路径。 //也可指定请求路径,如/text,则只能接收http://localhost:3000/text的请求 app.get('*', (req, res) => { //接收要转发的http地址 let url = req.url.substr(1); if(url.startsWith('http')){ const options = { url, method:"GET", //headers: req.headers //如果需要设置请求头,就加上 } request(options, function (error, response, body) { if (!error && response.statusCode === 200) { //拿到实际请求返回的响应头,根据具体需求来设置给原来的响应头 let headers = response.headers; res.setHeader('content-type',headers['content-type']); res.send(body); } else { res.send(options); } }); } }) app.post('*', (req, res) => { console.log(req.headers) console.log(req.body) let url = req.url.substr(1); if(url.startsWith('http')){ const options = { url, method: 'POST', json: req.body, //content-type是application/json的时候使用,其它请查看requiest用法 headers: { token: req.headers.token, 'content-type': req.headers['content-type'] } } request(options, function (error, response, body) { console.log(body,response,error) if (!error) { let headers = response.headers; res.setHeader('content-type',headers['content-type']); // for(let key in headers){ // res.setHeader(key,headers[key]); // } console.log(body) res.send(body); } else { res.send(options); } }); } // res.send('Hello World!') }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
重新运行 index.js 就可以代理post请求了,用postMan测试通过
同样需要注意的是请求头和响应头,以及参数的传递
本案例是经过本地测试过的,但是毕竟接口要求可能不一样,所以有些需要修改才能使用
步骤5:如果遇到跨域
加入以下代码允许跨域
// 允许跨域 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", '*'); res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); res.header("Access-Control-Allow-Credentials","true"); if(req.method === "OPTIONS") res.send(200); else next(); });
完整代码:
const express = require('express'); const app = express(); const port = 3000; //端口号 const request = require('request'); var bodyParser = require('body-parser') //只要加入这个配置,在req请求对象上会多出来一个属性 //parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) //parse application/json app.use(bodyParser.json()) // 允许跨域 app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", '*'); res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); res.header("Access-Control-Allow-Credentials","true"); if(req.method === "OPTIONS") res.send(200); else next(); }); //监听请求 *代表所有的请求路径。 //也可指定请求路径,如/text,则只能接收http://localhost:3000/text的请求 app.get('*', (req, res) => { //接收要转发的http地址 let url = req.url.substr(1); if(url.startsWith('http')){ const options = { url, method:"GET", //headers: req.headers //如果需要设置请求头,就加上 } request(options, function (error, response, body) { if (!error && response.statusCode === 200) { //拿到实际请求返回的响应头,根据具体需求来设置给原来的响应头 let headers = response.headers; res.setHeader('content-type',headers['content-type']); res.send(body); } else { res.send(options); } }); } }) app.post('*', (req, res) => { console.log(req.headers) console.log(req.body) let url = req.url.substr(1); if(url.startsWith('http')){ const options = { url, method: 'POST', json: req.body, //content-type是application/json的时候使用,其它请查看requiest用法 headers: { token: req.headers.token, 'content-type': req.headers['content-type'] } } request(options, function (error, response, body) { console.log(body,response,error) if (!error) { let headers = response.headers; res.setHeader('content-type',headers['content-type']); // for(let key in headers){ // res.setHeader(key,headers[key]); // } console.log(body) res.send(body); } else { res.send(options); } }); } // res.send('Hello World!') }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })