在一个项目中,初期的一部分接口是由.net开发的,后期的一部分接口是由java语言开发的,造成了一个项目内两中不同的语言开发的接口,这种情况下,不同的语言接口所在的服务器以及接口域名肯定是不同的,怎么解决系统内去请求不同域名的接口。
拿目前的项目举例,有一个文件是专门放接口名字的(url.js),一个封装axios拦截器等相关配置的文件(request.js),我们要解决在本地以及测试生产上都可以顺利的请求不同的接口
一、首先.net的接口和java接口名字如下代码:
//url.js
let serverUrl = '/'
if (window.location.host === 'localhost:3000') {
serverUrl = 'http://localhost:3000/'
}
const joint = url => {
return serverUrl + url
}
const allUrl = {
common: {
// .net的接口统一为DesktopModules开头
GetUserInfo: joint('DesktopModules/WS/API/MobileLogin/GetUserInfo'),
// java的接口统一为wsapi开头
loginNew: joint('wsapi/blade-system/login-system'),
},
}
export default allUrl
二、最重要的就是要配置axios请求的文件,通常我们在配置axios请求时只封装一套就可以了,以目前情况想到的办法就是封装两套,以get请求为例
//request.js
//在此处创建一个.net或者java的请求配置变量————service
const netService = axios.create({
baseURL: 'http://10.5.xx.xxx/', // 测试
timeout: 60000,
headers: {},
withCredentials: true,
crossDomain: true
})
/**
* 设置请求拦截器,添加token
*/
netService.interceptors.request.use(
config => {
//此处可以添加一些相关请求需要的参数,例如请求头等,代码有点多,我删掉一部分
if (config.method === 'post') {
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded;charset=UTF-8') {
config.data = qs.stringify(config.data)
}
}
return config
},
error => {
Toast.info('请求出错' + error)
return Promise.reject(error);
}
)
/**
* 设置响应拦截器
*/
netService.interceptors.response.use(
response => {
return response.data
},
error => {
if (error && error.response) {
let origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
if (error.response.status === 401) {
Toast.info('登录信息过期,即将跳转登录!')
setTimeout(() => {
window.open(`${origin}`, "_self");
}, 2000);
} else {
Toast.offline('请求错误')
}
console.log('拦截错误信息error.response', error.response)
} else {
Toast.offline('拦截错误信息error', error)
}
return Promise.reject(null)
}
)
/**
* @param {请求地址} url
* @param {请求参数} params
* 以get请求为例,定义如下方法即可
*/
export const netGet = (url, params = {}) => {
return netService.get(url, { params: params })
}
再封装一个请求java接口的方法
//java接口,需要定义另外一个变量,我用的是javaService
const javaService = axios.create({
baseURL: 'http://m.intuat.sinopec.com/', // 测试
timeout: 60000,
headers: {},
withCredentials: true,
crossDomain: true
})
/**
* 设置请求拦截器,添加token
*/
javaService.interceptors.request.use(
config => {
if (config.method === 'post') {
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded;charset=UTF-8') {
config.data = qs.stringify(config.data)
}
}
return config
},
error => {
Toast.info('请求出错' + error)
return Promise.reject(error);
}
)
/**
* 设置响应拦截器
*/
javaService.interceptors.response.use(
//此方法与.net的内容相同
response => {
return response.data
},
error => {
return Promise.reject(null)
}
)
/**
* @param {请求地址} url
* @param {请求参数} params
*/
export const javaGet = (url, params = {}) => {
return javaService.get(url, { params: params })
}
export default {
netGet, javaGet
}
三、此时接口请求方式已经封装好了,在相应的组件直接引用即可
//举例
//在需要调用接口组件引入request文件以及url.js文件
import http from '../../servers/request'
import url from '../../servers/url'
//在需要调用接口的地方直接使用
useEffect(()=>{
//在此处去调用对应的请求方式即可
http.javaGet(url.xxx.xxx,).then(res => {
console.log(res)
})
},[])
//调用.net的接口
useEffect(()=>{
//在此处去调用对应的请求方式即可
http.netGet(url.xxx.xxx,).then(res => {
console.log(res)
})
},[])
四、解决跨域问题
本地跨域:react项目在本地调试时可以配置代理,目前项目中用到的是http-proxy-middleware中间件来解决本地跨域问题
const { createProxyMiddleware } = require('http-proxy-middleware');
//在url.js中已经区分了不同服务的接口名字,不同的服务有统一的开头,根据不同的开头配置不同的代理
module.exports = function (app) {
app.use(createProxyMiddleware('/DesktopModules', {
target: 'http://10.5.xx.xxx',
secure: false,
changeOrigin: true
}));
app.use(createProxyMiddleware('/wsapi', {
target: 'http://intuat.sinopec.com',
secure: false,
changeOrigin: true
}));
};
测试生产跨域:request.js文件中根据不同的服务配置了不同的baseURL,但是最后我们项目的域名只是其中的一个,那么需要把.net或者java的baseURL改成相同的域名,然后域名后面加一个标识,后端可以通过该标识去映射对应的域名,即可解决
//例如.net的接口,在域名后面加一个net标识,与后端沟通好即可
const netService = axios.create({
baseURL: 'http://m.intuat.sinopec.com/net/',
timeout: 60000,
headers: {},
withCredentials: true,
crossDomain: true
})
以上就是解决一个项目中既有.net的接口又有java接口的办法,如有其他办法欢迎探讨。
此外,由于生产与测试域名也是不同的,可以配置环境变量来区分测试与生产。