失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【React跨域】react ajax配置代理的两种方式--- proxy/setupProxy

【React跨域】react ajax配置代理的两种方式--- proxy/setupProxy

时间:2019-04-11 12:33:01

相关推荐

【React跨域】react ajax配置代理的两种方式--- proxy/setupProxy

文章目录

🍩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》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。