现在很多web应用都是基于b\s架构并且实现前后端分离,当前端(js)向后端发送请求响应数据,但是由于浏览器的同源策略,会产生跨域问题。
解决跨域最好的方式推荐后端通过CORS方案解决,但是某些情况下后端程序如果为第三方或者沟通不方便的情况下,通用的解决方法为前端配置代理。
我们当前环境为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 (
)
}
}
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)]
在项目src\pacage.json追加如下配置:
"proxy": "http://localhost:10010"
说明:
请求url示例如下:
'http://localhost:3000/students'
第一步,安装库文件‘http-proxy-middleware’ ,当前脚手架默认安装了该库文件,所以我们可以省略这步。
第二步,创建代理配置文件,在src目录下,文件名字固定,其他名字不识别
setupProxy.js
第三步,编写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].