24.1React 中的 Axios 代理配置
跨域
说明
- react 本身只关注界面,并不包含发送 ajax 请求的代码。
- 前端应用需要用过 ajax 请求与后端进行交互。
- react 应用中需要集成第三方 ajax 库。
常用的 Ajax 库
- jQuery:比较重,如果需要另外引入,这里开发不建议使用。
- axios:量级比较轻,建议使用。
- 封装 XmlHttpRequest 对象的 ajax。
- promise 风格。
- 可以用在浏览器端和 node 服务器端
Axios 安装
安装很简单,使用 vue 项目的时候也是这个步骤。
npm install axios
Axios 使用
使用的话超级简单了,这个不是 react 的范畴,看一下 Axios 的 API 基本使用方法就可以会了。
案例: 比如有一个页面,页面很简单就一个按钮,我点击按钮的时候发一个 get 请求,展示一下获取到的数据就可以,很简单吧,稍微写一下
// 创建外壳组件
import React, { Component } from "react";
import axios from 'axios'
// 创建并暴露APP组件
export default class App extends Component {
// 获取验证码信息
getCodeData = () => {
// axios 请求案例
axios.get('http://192.168.67.27/nbiot/sys/sysConfig/getConfig').then(
response => {
console.log("请求成功了!", response.data) // 请求成功,打印一下数据
},
error => {
console.log("请求失败了!", error) // 请求失败,打印一下错误
}
)
}
render() {
return (
<div>
<button onClick={this.getCodeData}>获取验证码信息</button>
</div>
)
}
}
我们保存看一下效果哈。
好的,没啥展示的,就一个按钮。然后,重点来咯!!我们点击按钮看一下能不能获取到数据
好的非常棒! 前端开发经常遇到的问题出现了,跨域问题!
为啥会出现跨域问题?我们前端的地址是多少?localhost:3000
对吧?但是我们请求的服务器地址是多少?192.168.67.27
对吧?当客户端和服务端 IP、端口、协议
只要有一个不同,就会出现跨域问题对吧?是的,这里就是。
【拓展】那再问一下哈,跨域问题造成了什么结果?在直接一点,跨域导致了请求没有发送出去,还是跨域造成了数据没有接收回来啊?这里是第二种哈,请求发送了,服务器也接收到了,服务器也返回数据了,但是浏览器发现跨域,阻止了数据的接收。
解决跨域问题
因为跨域问题不是后端没有收到请求,而是前端浏览器为了保证安全进行的阻拦,所以说我们有很多种方式解决跨域问题。
解决跨域的方式主要有下面四种:
- 浏览器取消跨域阻拦。
- 后端处理允许跨域。
- package.json 实现跨域配置。
- setupProxy.js 实现跨域配置。
首先第一种,基本上没有人用,因为这个要给浏览器进行设置,但是呢,这个设置又不是默认的,所以说你自己电脑可以实现了,但是别人电脑不能用,白瞎。直接放弃!
第二种很多服务器都会设置,但是不代表每个后台开发的兄弟们愿意支持,所以说有用,但是对于前端来说不确定性太大,暂不考虑。
第三种和第四种是前端开发解决跨域最常用的,我们重点看这两种方式,我们先看第三种,这个最简单!
package.json 实现跨域配置
这个方式很简单,我们不能从 localhost:3000
发送数据到 192.168.67.27:80
那我们就找一个中间件,我们前端请求数据先把请求给中间件,然后中间件对数据请求进行一个转发,也就是代理,代理到服务器,服务器同样返回数据给中间件,中间件在把返回的数据转发给前端,就是这样一个流程。
注意,这个中间件已经是在客户端吧?不然的话跨域问题还是解决不了啊,IP、端口、协议
必须和前端一致啊!
那么这个中间件怎么实现呢?react 脚手架工具帮助我们实现了,我们只需要简单的配置就可以了。
我们看怎么配置。
首先我们点击按钮请求的接口是 http://192.168.67.27/nbiot/sys/sysConfig/getConfig
但是前端地址是 localhost:3000
我们需要使用中间件,把从 localhost:3000
发送的请求 代理到 http://192.168.67.27
去就可以了。
只需要这样配置。
在 package.json
文件最后 添加一段配置:
"proxy": "http://192.168.67.27"
修改完成之后,一定要记得,重新服务。必须重启,不然无效!!!
然后,我们看请求的地方:
// 获取验证码信息
getCodeData = () => {
// axios 请求案例
axios.get('http://192.168.67.27/nbiot/sys/sysConfig/getConfig').then(
response => {
console.log("请求成功了!", response.data)
},
error => {
console.log("请求失败了!", error)
}
)
}
我们访问的接口是 192.168.67.27
这个地方也是需要修改的,不然没作用是吧,肯定还是会有跨域问题,那需要我们怎么修改呢?改成浏览器本地的地址。
// 获取验证码信息
getCodeData = () => {
// axios 请求案例
axios.get('http://localhost:3000/nbiot/sys/sysConfig/getConfig').then(
response => {
console.log("请求成功了!", response.data)
},
error => {
console.log("请求失败了!", error)
}
)
}
然后,保存,刷新看效果
好的,数据返回了,中间件代理成功。
【探讨】这个配置的流程是什么?这个是怎么实现跨域的呢?
我们现在不请求这个接口了,我们换一下。换成请求 index.html
// 获取验证码信息
getCodeData = () => {
// axios 请求案例
axios.get('http://localhost:3000/index.html').then(
response => {
console.log("请求成功了!", response.data)
},
error => {
console.log("请求失败了!", error)
}
)
}
刷新,点击按钮看效果
就是我们请求 index.html
时候,返回的数据是啥?仔细看,眼熟不?是不是就是我们 react 脚手架工具给我们创建的这个 public 文件夹下的 index.html
文件啊?
好的,那么这个配置的作用是什么呢!
很多人总结哈 这个配置,可以让本地请求前往配置的服务器去获取数据解决跨域问题。
我们看到前边几个案例,他们说的对,但是不全对,我们请求 index.html 的时候不是就是自己的吗?所以说重新总结一下:
package.json 文件中的 proxy 配置,会让本地的请求先前往本项目的 public 文件夹中找寻请求的数据,如果找寻不到,在去 proxy 配置的服务器查找。
比如我们不查找 index.html 了,我们请求 index2.html
// 获取验证码信息
getCodeData = () => {
// axios 请求案例
axios.get('http://localhost:3000/index2.html').then(
response => {
console.log("请求成功了!", response.data)
},
error => {
console.log("请求失败了!", error)
}
)
}
看效果:
为啥报404? 因为本地项目 public 下面没有 index2.html 文件吧? 那不是应该请求 配置里面 proxy 中服务器的 index2.html 文件吗? 是啊!请求了啊,也没有,所以报 404。
好的这是关于 package.json 实现跨域配置的方法,很简单。
setupProxy.js 文件实现跨域配置
这个相对来说复杂一点儿,但是记住就好,不需要太深究,因为具体项目里面,就启动项目的时候配置一次,不会说每次开发都修改,一般配置一次就不会再变了。
学习过 vue 的宝子们,应该不陌生,换了个写法,但是原理是一样的。
注意哈,我们先把根据 package.json 实现跨域配置的代码删掉,改回最开始的样子,然后重启项目。
首先我们需要在 src
文件夹下创建一个 setupProxy.js
文件,注意:位置、名字都不许变,变了就白瞎,不好使了就。
里面这样子写:
const proxy = require('http-proxy-middleware')
module.exports = function (app) {
app.use(
proxy('/api', {
target: 'http://192.168.67.27/nbiot',
changeOrigin: true,
pathRewrite: { '^/api': '' }
})
)
}
学习过 vue 的宝子们是不是很兴奋,这个结构我太熟了!啊哈哈哈,一样的哈。
写完之后,我们看请求那里。
// 获取验证码信息
getCodeData = () => {
// axios 请求案例
// 在target配置baseUrl的不写了,在剩下的部分最前头添加 /api 前缀
axios.get('/api/sys/sysConfig/getConfig').then(
response => {
console.log("请求成功了!", response.data)
},
error => {
console.log("请求失败了!", error)
}
)
}
我们记住,重启! 必须重启!
很多人遇到这个问题,但是有人没有,我说一下哈,但凡添加完 setupProxy.js 文件之后重启打不开,一般是这个地方错了。就是 setupProxy.js 文件,我们配置成这样:
// const proxy = require('http-proxy-middleware')
const { createProxyMiddleware: proxy } = require('http-proxy-middleware')
module.exports = function (app) {
app.use(
proxy('/api', {
target: 'http://192.168.67.27/nbiot',
changeOrigin: true,
pathRewrite: { '^/api': '' }
})
)
}
导入的时候
// 老版本这样配置
const proxy = require('http-proxy-middleware')
// 新版本这样配置
const { createProxyMiddleware: proxy } = require('http-proxy-middleware')
修改完成再次重启,就可以启动了哈。
我们把 setupProxy.js 里的配置稍微注释一下意思哈。
// const proxy = require('http-proxy-middleware')
const { createProxyMiddleware: proxy } = require('http-proxy-middleware')
module.exports = function (app) {
app.use(
proxy('/api', { // 遇到 /api 前缀的请求,就会触发该代理配置
target: 'http://192.168.67.27/nbiot', // 请求转发给谁
changeOrigin: true, // 控制服务器收到的响应头中的 Host 字段值 (建议都写)
pathRewrite: { '^/api': '' } // 重写请求路径(必须写)
})
)
}
好了,这个没需要特别注意的,如果需要在添加代理的话,在 app.use
中继续添加 proxy
就可以哈。
总结
-
package.json 实现跨域配置
- 配置简单,前端请求资源师可以不加任何前缀。
- 不能配置多个代理。
- 优先匹配前端资源。
-
setupProxy.js 实现跨域配置
- 可以配置多个代理,可以灵活的控制请求是否走代理。
- 配置繁琐,前端请求资源时也必须加前缀。
更多推荐
所有评论(0)