说明

  • react 本身只关注界面,并不包含发送 ajax 请求的代码。
  • 前端应用需要用过 ajax 请求与后端进行交互。
  • react 应用中需要集成第三方 ajax 库。

常用的 Ajax 库

  1. jQuery:比较重,如果需要另外引入,这里开发不建议使用。
  2. 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 实现跨域配置

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

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐