文章目录
🍩React ajax🍧前置小知识🍰说明 🧁常用的ajax请求库🍬使用axios发送请求📛问题🧃如何开启代理服务器?🧃如何配置多个代理服务器?🍩React ajax
在之前的一篇文章中,详细介绍了解决跨域的两种方式,今天主要讲在react脚手架中发送Ajax请求解决跨域的另外两种代理方式,有需要的话可以耐心看完哦🥰
🍧前置小知识
🍰说明
React本身只关注于界面, 并不包含发送ajax请求的代码前端应用需要通过ajax请求与后台进行交互(json数据)react应用中需要集成第三方ajax库
(或自己封装)🧁常用的ajax请求库
jQuery: 比较重, 如果需要另外引入不建议使用axios
: 轻量级,建议使用封装XmlHttpRequest对象的ajaxpromise风格可以用在浏览器端和node服务器端🍬使用axios发送请求
需求:
点击按钮,向服务器发送请求,获取学生数据
1️⃣首先需要在vscode安装axios
npm install axios
2️⃣然后使用node+express
搭建一个服务器:
server1.js:
const express = require('express')const app = express()//服务器搭建好了,并且服务一旦开启就会被use中间件监听到,打印出“有人请求服务器1了”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)})//服务器开启在5000端口app.listen(5000, (err) => {if (!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');})
由于浏览器地址栏默认发送的就是get请求,我们可以在地址栏输入:http://localhost:5000/students
按下回车键,查看服务是否可以成功返回数据:
3️⃣发送请求获取数据:
import React, {Component } from 'react'import axios from 'axios'export default class App extends Component {getStudentData = () => {axios.get('http://localhost:5000/students').then(response => {console.log('成功了', response.data) },error => {console.log('失败了', error) })}render() {return (<div><button onClick={this.getStudentData}>点我获取学生数据</button></div>);}}
当点击按钮时,控制台显示报错:
📛问题
No ‘Access-Control-Allow-Origin’ header:说明跨域了,违背了同源策略…由于react脚手架运行在3000端口,但是发送请求的服务器在5000端口,形成了跨端口访问的问题,违背了同源策略,所以访问失败。
如何解决呢?在react脚手架里通过代理
来解决。
代理是什么?所谓"中间人",3000端口运行着一个react脚手架,还运行着一个微小的服务器,就是”中间人“。
产生跨域本质上是ajax引擎把服务器返回的数据给拦住了,原先的react脚手架有Ajax引擎,把服务器返回的数据给拦住了。而代理没有Ajax引擎,不存在跨域的问题。
实现过程:
react脚手架3000发送请求给代理3000,代理3000转发请求给服务器5000,服务器5000返回响应的数据给代理3000,代理3000再把数据传给react脚手架3000。(代理好比中介)
🧃如何开启代理服务器?
方法一(最简单):
在package.json
中加一行代码(如下图),意思是:代理给5000端口的地址发送请求。
然后原先axios给5000端口号发送请求,需要改为3000端口号
,因为代理的端口号是3000。
getStudentData = () => {axios.get('http://localhost:3000/students').then(response => {console.log('成功了', response.data) },error => {console.log('失败了', error) })}
运行结果:
那么问题来了?axios所有的请求都转发给5000端口吗?答案:不是。
3000端口有的资源,代理服务器就不会转发给5000端口了,如果当请求了3000不存在的资源时,那么该请求会转发给5000。
总结说明:
优点:配置简单,前端请求资源时可以不加任何前缀。缺点:不能配置多个代理。工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)
当react脚手架要向多个服务器请求数据呢?上述方法就行不通了。接下来看方法二
方法二:
再增加一个服务器,模拟多个服务器进行测试。
server2.js
(5001端口)
const express = require('express');const app = express()app.use((request, response, next) => {console.log('有人请求服务器2了');next()})app.all('/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(5001, (err) => {if (!err) console.log('服务器2启动,已经监听到5001端口...')})
🧃如何配置多个代理服务器?
第一步:
在src文件夹下,新建一个文件,名为:setupProxy.js
(名字固定,react脚手架会自动找到此文件,加到webpack的配置里,而webpack配置使用的都是node中的语法,也就是CommonJS语法)。
所以setupProxy文件里面不能用前端人员熟悉的ES6的语法,需要用CommonJS语法(CommonJS语法是前端模块化的一种规范)。
第二步:
编写setupProxy.js
配置代理规则:
// 建立代理const {createProxyMiddleware } = require('http-proxy-middleware')module.exports = function (app) {app.use(// use()函数能传多个参数createProxyMiddleware('/api1', {//遇见/api1前缀的请求,就会触发该代理配置(所有带有/api1前缀的请求都会转发给5000)target: 'http://localhost:5000', changeOrigin: true,pathRewrite: {'^/api1': '' }}),createProxyMiddleware('/api2', {target: 'http://localhost:5001',changeOrigin: true,pathRewrite: {'^/api2': '' }}))}
对配置的属性解释:
target:
请求转发给谁(能返回数据的服务器地址)
changeOrigin:
控制服务器收到的请求头中Host字段的值(Host字段:标识着本次请求是从哪发出的)
⭐changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
⭐changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
⭐changeOrigin默认值为false,但我们一般将changeOrigin值设为true
pathRewrite: { '^/api1': '' }:
(必须写)重写请求路径:将请求路径里的/api1替换成一个空字符串,去除请求前缀,保证交给后台服务器的是正常请求地址。
说明:
优点:可以配置多个代理,可以灵活的控制请求是否走代理。缺点:配置繁琐,前端请求资源时必须加前缀。
App.jsx:
import React, {Component } from 'react'import axios from 'axios'export default class App extends Component {getStudentData = () => {axios.get('http://localhost:3000/api1/students').then(response => {console.log('成功了', response.data) },error => {console.log('失败了', error) })}getCarData = () => {axios.get('http://localhost:3000/api2/cars').then(response => {console.log('成功了', response.data) },error => {console.log('失败了', error) })}render() {return (<div><button onClick={this.getStudentData}>点我获取学生数据</button><button onClick={this.getCarData}>点我获取汽车数据</button></div>);}}
💿总体效果:
今天的分享就到这里啦 ✨
如果对你有帮助的话,还请👉🏻关注💖点赞🤞收藏⭐评论🔥哦
不定时回访哟🌹
如果觉得《【React跨域】react ajax配置代理的两种方式--- proxy/setupProxy》对你有帮助,请点赞、收藏,并留下你的观点哦!