解决跨域、同源策略-React中代理的配置
主要是解决同源策略的问题
何为同源策略?
因为我们React在3000端口,Vue在8080端口,而后台接口往往在5000,这种不同的端口之间就是一种跨域的问题了
如何解决呢?
使用代理:
①代理的端口和前端的端口是一样的(也就是下面的3000端口跑了一个脚手架,并且也运行了一个微小的代理服务器)
②代理为什么能够请求别的端口的服务器是因为 代理服务器上面没有ajax引擎(因为产生跨域是因为ajax引擎把请求拦住了,
而我们的代理就是基于没有ajax引擎,来进行转发的,所以代理拿到数据之后,因为和脚手架钱都都在同一个端口
所以,脚手架的ajax引擎就允许接收这个数据了
在React中如何实现?
在react中有两种方式可以开启
方法一:在package.js中设置proxy代理
在package.json 中设置 "proxy": "http://localhost:5000",并重启脚手架
====这个相当于就是把所有给3000端口发的请求,都转发给了5000端口
但是代码中,我们写后台接口的时候,要写3000端口,而不是写5000(虽然我们后台在5000端口,但是我们这里设置了把3000端口发的请求转发到5000端口,其实就相当于这个localhost:3000就是和前端同一个端口的微型代理服务器,这个服务器会把我们给他的请求转发到5000端口中的后台接口中
getStudentData = () => { axios.get('http://localhost:3000/students').then( response => {console.log('成功了', response.data);}, error => {console.log('getStudentData方法失败了', error)} ) }
注意点:
-
如果写成 axios.get('http://localhost:3000/index.html') 这个请求并不会向5000端口发送,因为本地的public代表的就是3000端口,因为public有index.html,所以本地有的了,就不会和服务器请求了
-
假如本地没有并且代理中转发给的服务器(5000)的也没有,那么就会报错404了
-
缺点:就是只能配置一个服务器端口,3000没有就找5000,那假如又另外一个5001端口的服务器呢?
-
这个时候就引入了第二种方法(为了配置多个端口的后台接口)
-
方法二:多后台接口代理配置
如果有多个服务器的话,就不能只是在packge.json中配置了
-
在src目录下,新建一个 setupProxy.js 文件(名字不能更改)
-
并且这个文件不能用ES6规范,而是要用CJS(commonJS)(因为这个文件不是给前端执行的,而是React会把这个文件加到webpack的配置文件里面,webpack里面用的是CJS的语法规范的)
const proxy = require('http-proxy-middleware') module.exports = function(app) { app.use( proxy('/api1', { target: 'http://localhost:5000', changeOrigin: true, pathRewrite: {'^/api1': ''} }), proxy('/api2', { target: 'http://localhost:5001', changeOrigin: true, pathRewrite: {'^/api2': ''} }) ) }
解释:
-
如果不加/api1,那么就没有机会把请求发给5000,加了之后,也要进行消去
-
所以就通过pathRewrite来消去
-
-
全部的该前缀的请求都会被转发到目标服务器
-
changeOrigin: true, // 控制服务器收到的响应头中Host字段的值(host表示请求从哪发出来的),如果没加服务器那边的host显示从3000端口来的,如果加了就显示从5000端口来的(也就是欺骗服务器,我和你在同一个端口,你要给我数据)
所以请求的代码格式就是:
getStudentData = () => { axios.get('http://localhost:3000/api1/students').then( response => {console.log('成功了', response.data);}, error => {console.log('getStudentData方法失败了', error)} ) }
相关注意事项:
-
要么前端通过两个方式解决,要么就后端通过cors来解决跨域问题(但是其实真正用cors解决跨域的网站很少,存在安全性问题)
-