题记: 处理跨域的方式有很多种,这次主要是介绍我们在react中开发不借助后端实现的跨域处理。
先看一下我的整个demo目录结构图:
问题出现:
下面是我的客户端代码,索要服务器数据:
import React, { Component } from 'react'
import axios from 'axios';
export default class App extends Component {
render() {
return (
<div>
<button onClick={this.getOneData}>按钮1,向服务器1索要数据</button>
<button onClick={this.getTwoData}>按钮2,向服务器2索要数据</button>
</div>
)
}
getOneData = () => {
axios.get('http://localhost:3001/index').then(res => {
console.log(res);
},err => {
console.log(err);
})
}
getTwoData = () => {
axios.get('http://localhost:3002/index').then(res => {
console.log(res);
},err => {
console.log(err);
})
}
}
服务器1的代码:
const express = require('express')
const app = express();
// 定义全局中间件
app.use((request, response, next) => {
console.log('啊哈,服务器111被访问了!!!');
next();
})
app.get('/index',(req, res) => {
res.send('服务器111返回数据')
})
app.listen(3001,() => console.log('服务器111成功启动!'))
服务器2代码类似1,只不过端口号为3002了。
结果毫不意外是出现了跨域问题了!
这里值得一提的是跨域是服务器这边实际能接受到客户端的请求,也能响应,只不过浏览器拦截了哦!
解决办法有:
方式一:通过package.json文件配置处理
在我们的React项目中是有一个名叫package.json
的文件的,我们稍加配置:
在其末尾追加:"proxy": "http://localhost:3001"
并在项目中的请求服务器地址改为'http://localhost:3000/index'
,也可省写为'/index'
但是这样会是有局限性的,当我们后端做了服务器的负载均衡时,我们的这种方式就不奏效了,因为这种方式只能适应跨域一个服务器的处理,多个服务器并不能得以解决。
方式二:通过配置文件setupProxy.js
setupProxy.js这个文件类似打包文件,react项目一开始就会执行其中的代码,那么怎么配置呢?如下:
// 引入代理模块 react中自带有这项模块,所以无需下载
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
proxy('/api1', { // 遇见/api1前缀的请求,就会触发该代理配置
target: 'http://localhost:3001', // 请求转发给谁
changeOrigin: true, // 控制服务器收到的请求头中Host的值
pathRewrite: {'^/api1':''} // 重写请求路径(让后端路由得以识别)
}),
proxy('/api2', { // 遇见/api2前缀的请求,就会触发该代理配置
target: 'http://localhost:3002', // 请求转发给谁
changeOrigin: true, // 控制服务器收到的请求头中Host的值
pathRewrite: {'^/api2':''} // 重写请求路径(让后端路由得以识别)
}),
)
}
这里配置了三个参数:
target
:就是请求服务器的网络地址
changeOrigin
:布尔值,为true时代表隐藏请求来源(这个来源就变为服务器自身的网址了),为false时显示来源:
为true时:在中间件打印:console.log('Host', request.get('Host'));
为false时:在中间件打印:console.log('Host', request.get('Host'));
pathRewrite
:重写请求路径,就是本身服务器没有设置代理配置的路由,重新变为服务器设有的路由地址。
在我们项目中的请求网络地址需改为:
这样跨域问题就能直接通过前端解决了。
同时获取多个服务器端的响应数据了: