zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

React:前端配置代理解决跨域问题

2023-09-11 14:22:28 时间

跨域是一个老生常谈的问题,不再过多的去解释什么是跨域了,着重记录在React项目中怎么去解决跨域,当然对于前端开发而言,绝大部分的跨域问题,都是通过代理的方式解决的!

而代理适用的场景是:在生产环境中不发生跨域,但在开发环境中会发生跨域!因此,我们只需要在开发环境中使用前端代理解决跨域即可,又称为开发代理!
在React中解决跨域,毫无疑问,也是使用开发代理解决!

目录

产生跨域问题

解决跨域问题:

简单方式:

复杂方式:


产生跨域问题

举例,我们需要在React项目中使用axios,请求这个网址拿数据

https://h5.ele.me/restapi/bgs/poi/reverse_geo_coding?latitude=34.60614175850704&longitude=112.43507808743286
import React, {Component} from 'react';
import axios from "axios";

class App extends Component {
    getData = async () => {
        const resp = await axios.get('https://h5.ele.me/restapi/bgs/poi/reverse_geo_coding?latitude=34.60614175850704&longitude=112.43507808743286')
        console.log(resp)
    }
    render() {
        return (
            <div>
                <button onClick={this.getData}>获取数据</button>
            </div>
        );
    }
}
export default App;

页面点击获取数据,在控制台上就会出现如下情况,毫无疑问,这是出现了跨域问题

解决跨域问题:

简单方式:

第一步:在react项目中,找到package.json文件,打开它,在里面添加如下代码!

 第二步:将axios请求地址更改如下:

/restapi/bgs/poi/reverse_geo_coding?latitude=34.60614175850704&longitude=112.43507808743286

第三步:重新启动项目,测试是否解决跨域

    getData = async () => {
        const resp = await axios.get('/restapi/bgs/poi/reverse_geo_coding?latitude=34.60614175850704&longitude=112.43507808743286')
        console.log(resp)
    }

点击效果如下:跨域已解决!

说下这种解决方式的优缺点:

优点:肉眼可见的简单

缺点:只能配置一个,当我的项目中有多个请求域名时,无法解决。。。

复杂方式:

第一步:找到src目录,在src下新建setupProxy.js文件

第二步:在setupProxy.js中配置具体的代理规则,在这里需要注意一下,你需要知道自己用的是React18最新的版本或者是React17的版本

React18:

//需要采用CommonJS的写法
const {createProxyMiddleware} = require('http-proxy-middleware')

module.exports = function (app) {
    app.use(createProxyMiddleware('/api-elm', //遇见/api-elm前缀的请求,就会触发该代理配置
            {
                target: 'https://h5.ele.me', //请求转发给谁(能返回数据的服务器地址)
                changeOrigin: true,  //控制服务器收到的响应头中Host字段的值
                pathRewrite: {'^/api-elm': ''} //重写请求路径,保证交给后台服务器是正常地请求地址(必须配置)
            }),
        createProxyMiddleware('/api-news',
            {
                target: 'https://pacaio.match.qq.com',
                changeOrigin: true,
                pathRewrite: {'^/api-news': ''}
            }))
}

React17:当你使用的是React18版本,但却是采用17的写法,那么会发现你的react项目无法连接,拒绝访问。。。

//需要采用CommonJS的写法
const proxy = require('http-proxy-middleware')

module.exports = function (app) {
    app.use(proxy('/api-elm', //遇见/api-elm前缀的请求,就会触发该代理配置
            {
                target: 'https://h5.ele.me', //请求转发给谁(能返回数据的服务器地址)
                changeOrigin: true,  //控制服务器收到的响应头中Host字段的值
                pathRewrite: {'^/api-elm': ''} //重写请求路径,保证交给后台服务器是正常地请求地址(必须配置)
            }),
        proxy('/api-news',
            {
                target: 'https://pacaio.match.qq.com',
                changeOrigin: true,
                pathRewrite: {'^/api-news': ''}
            }))
}

特别说明:setupProxy.js不需要去引入到任何文件,在开发运行的时候,会自动帮我们注册

第三步:修改组件请求代码,重启项目

import React, {Component} from "react";
import axios from "axios";

class App extends Component {
    getAddressData = () => {
        axios.get('/api-elm/restapi/bgs/poi/reverse_geo_coding?latitude=34.841673&longitude=113.675712').then(resp => {
            console.log(resp)
        }).catch(err => {
            console.log(err)
        })
    }
    getNewsData = async () => {
        const response = await axios.get('/api-news/irs/rcd?page=1&num=20&expIds=20220620V0103G00%7C20220620V017LK00%7C20220617V098W60&cid=56&ext=sports_nba&token=c786875b8e04da17b24ea5e332745e0f')
        console.log(response)
    }

    render() {
        return (
            <div>
                <button onClick={this.getAddressData}>获取地址数据</button>
                <button onClick={this.getNewsData}>获取新闻数据</button>
            </div>
        );
    }
}

export default App;

点击效果如下:

说下这种解决方式的优缺点:

优点:可以配置多个代理,可以灵活的控制请求是否需要走代理。

缺点:配置比较繁琐,前端请求资源时必须加前缀。