React 入门:脚手架代理配置

React Ajax

  • 理解

    • React 本身只关注于界面,并不包含发送 ajax 请求的代码。
    • 前端应用需要通过 ajax 请求与后台进行交互(json 数据)。
    • React 应用中需要继承第三方 ajax 库(或自己封装)。
  • 常用 ajax 请求库

    • jQuery:比较重,如果需要另外引入,不建议使用。
    • axios:轻量级,推荐使用

Axios

Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。

在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

  • 特性

    • 从浏览器创建 XMLHttpRequests
    • 从 node.js 创建 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求和响应数据
    • 取消请求
    • 自动转换 JSON 数据
    • 客户端支持防御 XSRF
  • 安装

    • npm 安装命令:
    npm install axios
    
    • 通过 Yarn 安装:
    yarn add axios
    

    想学习和了解更多 axios 内容,请访问 Axios 中文网

在 React 中使用 Axios

通过一个简单的代码实例来演示,这里需要提前准备好两个 api 服务器,如果没有准备好,请阅读上一篇文章,代码如下:

// file: src/App.js

import React, { Component } from "react";
import axios from "axios"; // 导入 axios

export default class App extends Component {
  getStudentData = () => {
    axios.get("http://127.0.0.1:5000/students").then(
      (response) => {
        console.log("成功:", response.data);
      },
      (error) => {
        console.log("失败:", error);
      }
    );
  };
  getCarsData = () => {
    axios.get("http://127.0.0.1:5001/cars").then(
      (response) => {
        console.log("成功:", response.data);
      },
      (error) => {
        console.log("失败:", error);
      }
    );
  };

  render() {
    return (
      <div>
        <button onClick={this.getStudentData}>点我获取学生数据</button>
        <button onClick={this.getCarsData}>点我获取汽车数据</button>
      </div>
    );
  }

首先运行 node server1.jsnode server2.js 命令,启动两台服务器;
然后运行 React 代码,点击界面上的【点我获取学生数据】按钮和【点击获取汽车数据】按钮,浏览器控制台都会报出如下跨域问题:
在这里插入图片描述

扩展
基于上面的问题,简单介绍一下跨域相关概念。

  • 首先,什么是跨域呢?
    跨域指的是浏览器不能执行其他网站的脚本,简单来说是浏览器同源政策的限制,浏览器针对于 ajax 的限制。
  • 同源政策
    两个页面拥有相同的协议,端口,域名 就是同源,如果有一个不相同就是不同源。同源政策产生的目的是为了保护用户信息安全,防止一些网站盗取用户信息。

那么,在 React 中如何解决跨域的问题呢?这就引出了本文的正题,—— 代理。(当然还可以通过其他方式解决跨域问题,如 jsonp、nginx 反向代理等。)

脚手架代理配置

  • 什么是代理
    常说的代理就是一个代理服务器,例如 A 服务器请求 B 服务器,我们可以通过代理 C 服务器去帮助我们请求,产生的跨域原因就是浏览器的同源政策是针对于 ajax 的请求,并不限制服务器之间的通信传输,而这个代理服务器正是和我相同端口域名的,我只需去用代理服务器去发请求再去接收,从而达到跨域。

  • 两种配置方式

    • 方式一
      在 package.json 中追加如下代码:

      "proxy": "http://127.0.0.1:5000"
      

      说明

      • 优点:配置简单,前端请求资源时可以不加任何前缀。
      • 缺点:不能配置多个代理。
      • 工作方式:上述方式配置代理,当请求了 3000 不存在的资源,那么该请求会转发给 5000(优先匹配前端资源)。

      实战

      • 首先,上面 App.js 中的 getStudentData 方法中 axios.get 第一个参数请求 url 中的 端口要改成 3000,代码如下:

        getStudentData = () => {
          axios.get("http://127.0.0.1:3000/students").then(
            (response) => {
              console.log("成功:", response.data);
            },
            (error) => {
              console.log("失败:", error);
            }
          );
        };
        
      • 然后,在 package.json 中第一层添加 "proxy": "http://127.0.0.1:5000",注意一定要不要写错位置了,可参照下面的截图:
        在这里插入图片描述

      • 最后,由于更改了 package.json 文件,需要运行 yarn start 重启 React 应用,代理才能起作用,此时在浏览器中打开的页面中点击【点我获取学生数据】按钮,就可以正常返回数据了,截图如下: 在这里插入图片描述

    • 方式二
      第一步,创建代理配置文件。在 src 下创建配置文件:src/setupProxy.js。
      第二步,编写 setupProxy.js 配置具体代理规则:

      // file:src/setupProxy.js
      
      const proxy = require("http-proxy-middleware");
      
      module.exports = function (app) {
        app.use(
          // /api1是需要转发的请求(所有带有/api前缀的请求都会转发给5000)
          proxy("/api1", {
            target: "http://127.0.0.1:5000", // 配置转发目标地址(能返回数据的服务器地址)
            changeOrigin: true, // 控制服务器接收到的请求头中Host字段的值
            /*
              changeOrigin 设置为 true 时,服务器收到的请求头中的 host 为:localhost:5000
              changeOrigin 设置为 false 时,服务器收到的请求头中的 host 为:localhost:3000
              changeOrigin 默认为 true ,但我们一般将 changeOrigin 值设为 true
             */
            pathRewrite: { "^/api1": "" }, // 重写请求路径,去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
          }),
          proxy("/api2", {
            target: "http://127.0.0.1:5001",
            changeOrigin: true,
            pathRewrite: { "^/api2": "" },
          })
        );
      };
      

      说明

      • 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
      • 缺点:配置繁琐,前端请求资源时必须加前缀。

      实战

      • 首先,确保已经在 src 下创建配置了 setupProxy.js 文件,且正确编写了代理规则;

      • 然后,修改 App.js 中的 axios 请求地址,代码如下:

        getStudentData = () => {
          axios.get("http://localhost:3000/api1/students").then(
            (response) => {
              console.log("成功:", response.data);
            },
            (error) => {
              console.log("失败:", error);
            }
          );
        };
        getCarsData = () => {
          axios.get("http://localhost:3000/api2/cars").then(
            (response) => {
              console.log("成功:", response.data);
            },
            (error) => {
              console.log("失败:", error);
            }
          );
        };
        
      • 最后,需要运行 yarn start 重启 React 应用,代理才能起作用,此时在浏览器中打开的页面中分别点击【点我获取学生数据】按钮和【点我获取汽车数据】按钮,就可以正常返回数据了,截图如下: 在这里插入图片描述

      如果浏览器报错如下:
      setupProxy VM200:6772 crbug/1173575, non-JS module files deprecated

      解决方式是,使用下面的新的写法:

      // file:src/setupProxy.js
      
      const proxy = require("http-proxy-middleware");
      
      module.exports = function (app) {
        app.use(
          // /api1是需要转发的请求(所有带有/api前缀的请求都会转发给5000)
          proxy.createProxyMiddleware("/api1", {
            target: "http://127.0.0.1:5000", // 配置转发目标地址(能返回数据的服务器地址)
            changeOrigin: true, // 控制服务器接收到的请求头中Host字段的值
            /*
              changeOrigin 设置为 true 时,服务器收到的请求头中的 host 为:127.0.0.1:5000
              changeOrigin 设置为 false 时,服务器收到的请求头中的 host 为:127.0.0.1:3000
              changeOrigin 默认为 true ,但我们一般将 changeOrigin 值设为 true
             */
            pathRewrite: { "^/api1": "" }, // 重写请求路径,去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
          }),
          proxy.createProxyMiddleware("/api2", {
            target: "http://127.0.0.1:5001",
            changeOrigin: true,
            pathRewrite: { "^/api2": "" },
          })
        );
      };
      

    无论使用哪种方式,都可以解决上文跨域的问题。

    注意 无论使用哪种代理方式,一定要重新启动 React 才能生效!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西涯三锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值