> 文章列表 > 0401脚手架配置代理-ajax-react

0401脚手架配置代理-ajax-react

0401脚手架配置代理-ajax-react

1 场景

  • 跨域

现在很多web应用都是基于b\\s架构并且实现前后端分离,当前端(js)向后端发送请求响应数据,但是由于浏览器的同源策略,会产生跨域问题。

  • 关于同源策略和跨域问题的产生,可参考==跨域问题及跨域解决方案汇总==

解决跨域最好的方式推荐后端通过CORS方案解决,但是某些情况下后端程序如果为第三方或者沟通不方便的情况下,通用的解决方法为前端配置代理。

2 脚手架配置代理

2.1 测试环境

  • 后端测试环境

我们当前环境为react脚手架配置代理,后端测试环境为Node+Express。

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(10010,(err)=>{if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:10010/students');
})

server2.js源代码如下所示

const express = require('express')
const app = express()app.use((request,response,next)=>{console.log('有人请求服务器2了');next()
})app.get('/cars',(request,response)=>{const cars = [{id:'001',name:'奔驰',price:199},{id:'002',name:'马自达',price:109},{id:'003',name:'捷达',price:120},]response.send(cars)
})app.listen(10011,(err)=>{if(!err) console.log('服务器2启动成功了,请求汽车信息地址为:http://localhost:10011/cars');
})

在vscode控制台分别启动两个服务,命令如下:

node server1.js
node server2.js
  • 前端测试环境

react脚手架create-react-app创建项目去除暂时不需要的文件,使用异步通信组件axios,App.jsx如下所示:

// 创建外壳组件App
import {Component} from 'react'
import axios from 'axios'class App extends Component {getStudentData = () => {axios.get('http://localhost:10010/tudents').then(resp => {console.log('成功类', resp.data);},err => {console.log('失败类', err)})}getCarData = () => {axios.get('http://localhost:10011/cars').then(resp => {console.log('成功类', resp.data);},err => {console.log('失败类', err)})}render() {return (<div><button onClick={this.getStudentData}>点我获取学生数据</button><br/><button onClick={this.getCarData}>点我获取汽车数据</button><br/></div>)}}export default App

启动项目直接点击获取学生数据,报跨域错误,如下图2.1-1所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xNedLX4v-1681122638160)(/Users/gaogzhen/baiduSyncdisk/study/front/react/note/04ajax/images/截屏2023-04-10 18.00.48-error-cors-policy.png)]

2.1 配置方式1

在项目src\\pacage.json追加如下配置:

"proxy": "http://localhost:10010"

说明:

  • 优点:配置简单,前端请求资源时可以不加任何前缀
  • 缺点:不能配置多个代理。
  • 工作方式:当请求3000端口存在资源时,会将该请求转发为配置代理的端口(优先查找本地资源)

请求url示例如下:

'http://localhost:3000/students'

2.2 配置方式2(推荐方式)

  1. 第一步,安装库文件‘http-proxy-middleware’ ,当前脚手架默认安装了该库文件,所以我们可以省略这步。

  2. 第二步,创建代理配置文件,在src目录下,文件名字固定,其他名字不识别

    setupProxy.js
    
  3. 第三步,编写setupProxy.js配置具体代理规则

setupProxy.js配置具体代理规则根据’http-proxy-middleware’版本的不同,配置方式不一样

当前库文件版本为2.0.6,我们以配置2个代理为例,配置规则代码2.2-1如下所示:

const { createProxyMiddleware } = require("http-proxy-middleware")
module.exports = function (app) {app.use(createProxyMiddleware("/api1",{target: "http://localhost:10010", //配置转发目标地址(能返回数据的服务器地址)changeOrigin: true, //控制服务器接收到的请求头中host字段的值pathRewrite: { "^/api1": "" }, // 重写规则}),createProxyMiddleware("/api2",{target: "http://localhost:10011", //配置转发目标地址(能返回数据的服务器地址)changeOrigin: true, //控制服务器接收到的请求头中host字段的值pathRewrite: { "^/api2": "" }, }))
}

如果是早期版本,配置规则代码2.2-2如下所示:

const proxy = require('http-proxy-middleware')module.exports = function(app){app.use(proxy('/api1', {target: 'http://127.0.0.1:10010',changeOrigin: true,pathRewrite: {'^/api1': ''}}),proxy('/api2', {target: 'http://127.0.0.1:10011',changeOrigin: true,pathRewrite: {'^/api2': ''}}),) 
}

至于那个版本算早期,这里没有去测试对比或者深入研究源码,有知道可以告诉我一下。

相应的请求url地址如下所示:

'http://localhost:3000/api1/students'

结语

❓QQ:806797785

⭐️源代码仓库地址:https://github.com/gaogzhen/react-staging.git

参考:

[1]React视频教程[CP/OL].2020-12-15.p65-66.

[2]React官网[CP/OL].

[3]ChatGPT[CP/OL].