接口代理的概念
正向代理
代理客户端去请求服务器,隐藏了真实客户端,服务器并不知道真实的客户端是谁。
反向代理
反向代理隐藏了真正的服务端,就像你每天使用百度的时候,只知道敲打www.baidu.com就可以打开百度搜索页面,但背后成千上万台百度服务器具体是哪一台为我们服务的,我们并不知道。我们只知道这个代理服务器,它会把我们的请求转发到真实为我们服务的那台服务器那里去。
接口代理的简单实现
一般来说,前端开发者多用正向代理的接口代理方式。所以实现的时候需要一个服务端和一个客户端。
客户端
客户端向服务端发起请求:
import axios from 'axios'
// 以/github/开头的url被认为是需要代理的接口
axios
.get('/github/search/repositories?q=react')
.then(res => console.log(res))
服务端
服务端接收到客户端的请求之后,根据路径或其他的参数进行真正的请求路径的拼接,设置相关的字段之后,由服务器发起对外网服务器的请求,再由服务器返回外网服务器返回的数据给客户端。
// proxy.js
/**
* github接口代理,防止因请求过多而被禁用ip,并且添加认证头部
*/
const githubBaseUrl = 'https://api.github.com';
const axios = require('axios');
module.exports = server => {
server.use(async (ctx, next) => {
const path = ctx.path;
// path以/github/开头,则被认为是一个需要代理的接口
if (path.startsWith('/github/')) {
// 获取当前的token和token_type
const githubAuth = ctx.session.githubAuth;
// 对应的github接口地址
const githubPath = `${githubBaseUrl}${ctx.url.replace('/github/', '/')}`;
const token = githubAuth && githubAuth.access_token;
// 根据token的有无增加字段
let headers = {};
if (token) {
headers['Authorization'] = `${githubAuth.token_type} ${token}`
}
try {
const res = await axios({
method: 'get',
url: githubPath,
headers
});
if (res.status === 200) {
// 返回数据
ctx.body = res.data;
// 设置响应头
ctx.set('Content-Type', 'application/json')
} else {
ctx.status = res.status;
ctx.body = {
success: false,
};
ctx.set('Content-Type', 'application/json')
}
} catch (e) {
ctx.body = {
success: false,
};
ctx.set('Content-Type', 'application/json')
}
} else {
await next()
}
})
};
// server.js
const Koa = require('koa');
const Router = require('koa-router');
const server = new Koa();
const router = new Router();
server.use(router.routes());
const proxy = require('./proxy');
proxy(server)