React学习-配置代理
发表于|更新于
|阅读量:
为什么要配置代理?
在React中,通常需要展示后端发送来的数据,前后端分离,下面是一个React请求后端发来的数据的例子
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import React, { Component } from 'react' import axios from 'axios'
export default class App extends Component {
getStudentsData = () => { axios.get('http://localhost:5000/students').then( response => {console.log("成功了",response.data)}, error => {console.log("失败了",error)} ) } render() { return ( <div> <button onClick={this.getStudentsData}>点击获取学生数据</button> </div> ) } }
|
react 请求位于5000端口的服务器的学生数据,获取返回信息输出在控制台
开启客户端 npm start,在3000端口
server1.js
服务端代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const express = require('express')
const app = express()
app.use((req,res, next)=>{ console.log('server1接收请求') next(); })
app.get('/students',(req,res)=>{ console.log('server1接收到请求') res.json({ message: 'student数据' }); })
app.listen(5000, ()=>{ console.log('server1 running at http://127.0.0.1:5000') })
|
服务端接收到来自客户端的请求后,会返回学生数据。
开启服务器,node server1.js,服务器端口监听5000端口。
当发送请求后,得到的结果如下图所示
报错Access-Control-Allow-Origin,发生跨域请求的错误。
基本原因是因为前端使用底层的ajax来发送请求,从3000端口转发到5000端口,服务端是可以接收到请求的,但是无法返回给前端。
所以我们需要配置代理,通过发送请求给代理,代理帮我们转发到服务器。代理发送的请求不是通过ajax 底层发送的,所以不会报跨域的错误。
配置代理方法1
如何正确配置代理,有两种方法。
其中一种方法是修改前端配置文件package.json
新增代理字段"proxy": "http://localhost:5000",表示代理接收到请求后转发到localhost:5000 的地址,即此处的服务端的地址
因为前端现在需要发送给代理,而不是直接发送给服务端,所以需要改变前端的请求url,应该发送给3000端口。
重新启动,并发送请求,得到结果如下,成功返回数据
但是在使用这种方法需注意,因为现在请求的是3000端口,即前端的端口,所以如果请求的数据地址是前端的静态资源地址,容易造成直接将前端的静态资源返回给浏览器,不通过代理。
配置代理方法2
在上一种方法中的服务端代码serve1.js的基础上,新增server2.js的代码
在server2.js代码中,另开启一台服务器,开启在端口5001。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const express = require('express')
const app = express()
app.use((req,res, next)=>{ console.log('server2接收请求') next(); })
app.get('/cars',(req,res)=>{ res.json({ message: 'car数据' }); })
app.listen(5001, ()=>{ console.log('server1 running at http://127.0.0.1:5001') })
|
前端App.jsx新增另外一个请求按钮
1 2 3 4 5 6 7
| getCarsData = () => { axios.get('http://localhost:3000/cars').then( response => {console.log("成功了",response.data)}, error => {console.log("失败了",error)} ) }
|
此时会遇到一个问题,在package.json的配置文件中,我们只配置了一个代理,即所有发送给5000端口的数据都会经过这个代理转发。但是现在需要发送新的请求给5001端口,怎么办呢?
由于配置文件只能写一个代理,无法配置多个代理,所以我们使用方法2
在src文件夹下新建一个setupProxy.js的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) { app.use( createProxyMiddleware('/api1',{ target: 'http://localhost:5000', changeOrigin: true, pathRewrite: {'^/api1': ''} }) , createProxyMiddleware('/api2',{ target: 'http://localhost:5001', changeOrigin: true, pathRewrite: {'^/api2': ''} }) ); };
|
只有匹配到特定的api前缀才会转发数据,所以我们需要更改前端的url,
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| getStudentsData = () => { axios.get('http://localhost:3000/api1/students').then( response => {console.log("成功了",response.data)}, error => {console.log("失败了",error)} ) }
getCarsData = () => { axios.get('http://localhost:3000/api2/cars').then( response => {console.log("成功了",response.data)}, error => {console.log("失败了",error)} ) }
|
在服务端检查一下他的请求路径
server2.js
1 2 3 4
| app.get('/cars',(req,res)=>{ res.json({ message: 'car数据' }); console.log("请求路径",req.url) })
|
启动服务,发送请求,得到结果如下:
浏览器控制台:
服务器端:
成功输出路径,但是没有显示/api2,这是因为pathRewrite将/api2用空串替换