为了更好地理解如何在React应用程序中配置代理,我们需要先了解什么是代理。
代理是一种充当客户端和服务器之间中间人的服务器。当客户端向服务器发送请求时,代理服务器将接收请求并将其转发到服务器。服务器将响应发送回代理服务器,代理服务器再将响应发送回客户端。代理服务器可以用于多种目的,例如提高安全性、缓存响应、过滤请求等。
服务端代码
- 需要一个新的文件夹安装
express
依赖
npm i express
Express
是一个流行的Node.js
框架,用于构建Web
应用程序和API
。它提供了许多有用的功能,例如路由、中间件、模板引擎等等。
- 编写一个
server1.js
获取学生信息的请求
const express = require('express') const app = express() app.use((request,response,next)=>{ console.log('有人请求服务器1了'); console.log('请求来自于',request.get('Host')); console.log('请求的地址',request.url); next() }) app.get('/students',(request,response)=>{ const students = [ {id:'001',name:'tom',age:18}, {id:'002',name:'jerry',age:19}, {id:'003',name:'tony',age:120}, ] response.send(students) }) app.listen(5000,(err)=>{ if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students'); })
- 启动该服务
node server1.js
启动成功,控制台会打印以下信息:
服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students
客户端模拟请求
初始化脚手架src
文件夹里面的文件:App.jsx
|index.js
|components文件夹
为了进行网络请求,我们这里需要安装axios
第三方库来完成:
npm i axios
然后在App.jsx
文件里面进行模拟请求:
import React, { Component } from 'react' import axios from 'axios' export default class App extends Component { // 获取学生信息方法 getStuInfo = () => { axios.get('http://localhost:5000/students').then(res=>{ console.log(res) }, err=>{ console.log(err) }).catch(()=>{}) } render() { return ( <div> App.... <button onClick={this.getStuInfo}>点击我获取学生信息</button> </div> ) } }
查看效果:
我们看到了Access-Control-Allow-Origin
、CORS
字样时我们知道这是跨域了,以至于我们请求失败。
跨域是指在Web应用程序中,当一个域(例如example.com
)的JavaScript
代码试图访问另一个域(例如api.example.com
)的资源时发生的情况。这是由于浏览器的同源策略所导致的,该策略限制了来自不同源的JavaScript代码之间的交互。
这时就需要后端人员配置CORS
,或者我们前端自己配置代理。
配置代理
代理请求是指在服务器端进行请求的机制,通过使用代理,您可以将跨域请求发送到您自己的服务器,然后从服务器上进行请求。这将绕过浏览器的同源策略,并允许您访问其他域的资源
方式一
在package.json
中追加如下配置:
"proxy":"http://localhost:5000"
然后修改前端请求的路径:
// 获取学生信息方法 getStuInfo = () => { axios.get('http://localhost:3000/students').then(res=>{ console.log(res) }, err=>{ console.log(err) }).catch(()=>{}) }
这里只需要将端口5000
改为3000
,然后该请求就会通过代理拿到后台的学生数据。
说明:
- 优点:配置简单,前端请求资源时可以不加任何前缀。
- 缺点:不能配置多个代理。
- 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)
方式二
- 第一步:创建代理配置文件
在src下创建配置文件:src/setupProxy.js
- 编写
setupProxy.js
配置具体代理规则:
const proxy = require('http-proxy-middleware') module.exports = function(app) { app.use( proxy('/api1', { //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000) target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址) changeOrigin: true, //控制服务器接收到的请求头中host字段的值 /* changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000 changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000 changeOrigin默认值为false,但我们一般将changeOrigin值设为true */ pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置) }), proxy('/api2', { target: 'http://localhost:5001', changeOrigin: true, pathRewrite: {'^/api2': ''} }) ) }
- 改写请求路径
// 获取学生信息方法 getStuInfo = () => { axios.get('http://localhost:3000/api1/students').then(res=>{ console.log(res) }, err=>{ console.log(err) }).catch(()=>{}) }
最终也能请求成功。
说明:
- 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
- 缺点:配置繁琐,前端请求资源时必须加前缀。