上节课我们结束了整个TodoList
案例,而且也做了阶段性的总结。接下来我们将要进入到下一个环节:React ajax
。
回顾
- 用
reduce
方法来着条件统计 defaultChecked
只在第一次加载起作用- 要学会需求分析和功能实现思路分析
- 某个组件使用的数据存放在自身的
state
中 - 某些组件使用的数据存放在共同的父组件的
state
中 - 父组件给子组件传递数据直接通过
props
传 - 子组件给父组件传递数据需要父组件提前提供一个入口函数,并通过
props
将入口函数传给子组件,由子组件调用该入口函数
以上便是TodoList
案例的主要要点
前置说明
react
本身只关注界面,不包含发送ajax
请求的代码- 前端通过
ajax
请求与后台交互(json
数据) react
应用中需要集成第三方ajax
库(或者自己封装)
常用的ajax
请求库
jQuery
:比较重量级,而且直接操作DOM
,如果需要另外引入不建议使用axios
:轻量级,建议使用- 封装
XmlHttpRequest
对象的ajax
Promise
风格- 可以用在浏览器和
node
服务端
- 封装
安装axios
那么我们对比了jQuery
和axios
之后,也明确了我们更建议使用axios
,那么我们来写个示例看一看吧。首先我们创建一个新的项目。然后删除掉多余的文件,准备好容器,入口文件和App
组件。这是准备工作。
但是我们有项目了,脚手架里有axios
吗?是不是肯定没有的啊?那么我们既然要用肯定得安装啊。然后我们在命令行里进入到这个项目中去,然后执行命令npm i axios
来安装axios
库。
示例
既然安装了axios
,项目也有了,那么我们开始正式写一个样例来看看吧:
import React, { Component } from 'react'; import axios from 'axios'; export default class App extends Component { render() { return ( <div> <button onClick={this.getData}>Click</button> </div> ); } getData = () => { axios.get("http://localhost:5000/students").then( response => {console.log("success",response.data);}, error => {console.log("error",error);} ) } }
我们来看代码,首先导入React
这个我们就不多解释了,然后导入axios
,因为我们要用axios
来发送请求所以一定要引入的。我们这次直接在App
组件中来编写我们的样例,因为我们目前在联系的是axios
发送请求而不是组件化编码,所以为了方便就直接在App
组件中来写了。
然后看App
组件,我们就写了一个按钮,这个按钮我们绑定了onClick
事件,并将getData
方法作为事件回调。那么我们来看一看这个方法,直接axios.get
发送一个GET
请求,既然发送get
请求我们是不是要传入一个url
?不然我们请求发给谁呢?
另外一点axios
发送请求返回的是一个Promise
对象,那么我们是不是要调用then
方法来获取这个请求发送是成功了还是失败了?成功了的话是不是获取response
值,失败了我们要知道为什么失败啊,所以几首两个函数,但是Promise
是不是吧我们的数据都存放在response
的data
属性中了啊,所以我们要想获取数据就要调用response.data
。
这样的话,只要我们一点击按钮,是不是就会在控制台中打印出我们请求发送出去的情况?当然了我这里的这个url
是我自己准备好的一个测试接口,我会把这个接口单独附出来。那么我们看一下效果吧:
我们发现,诶控制台里面报错了,什么意思?这是不是在说我们跨域请求了啊?跨域的本质是什么?是因为同源策略的限制,但是同源策略都限制了些什么呢?这一部分内容大家如果不记得了,抓紧回去复习ajax
跨域问题。
我们这里就简单地看,我们的前端页面地址是不是localhost:3000
?而我们启动的的接口地址是不是localhost:5000
?那么我们在3000
端口给5000
端口发请求ajax
引擎能通过吗?肯定不行啊。但是我们思考一个问题,到底是因为跨域了我们请求发不出去,还是因为跨域了我请求发出去了但是数据回不来?这是两个概念,一种是连发请求都不能发,另一个是能发请求,但是拿不到数据。
实际上呢,我们其实是跨域发出去请求的,但是数据是无法传回来的,怎么证明呢?
我们的接口界面有提醒,有人请求了接口服务器,如果说请求发不出去的话,我们是不是根本就不会出现这个接口被请求的提醒?
但是我们现在前因后果都明白了,但是我们的这个问题怎么解决呢?我们在react
脚手架中跨域通过代理来解决这个问题。
代理是什么
看到这大家是不是要说终于到正题了,再不说可就忘了这节课的标题是配置代理了。但是代理到底是什么东西呢?我们怎么去理解呢?
这么说吧,当我们客户端 3000 端口要往服务端 5000 端口发送请求的时候,就一定要经过ajax
引擎,ajax
引擎发现客户端在 3000 端口,没问题,放行,但是服务端返回数据的时候,ajax
引擎发现这个数据来源是在 5000 端口的,那么就会直接拦截下来,因为跨域了。
但是代理是个啥呢?我招一个中间人,这个中间人是 3000 端口,这一定要注意,这个中间人一定要是和客户端在同一个端口,否则也还是跨域。
那么这个情况下我们再发请求,就是先给这个中间人发请求,然后这个中间人会把我们的请求转发给服务端。然后服务端再把这个数据返回给我们的这个中间人。但是这一步为什么能走得通呢?中间人也是 3000 端口啊,服务端从 5000 端口返回数据应该也被拦下来才对啊。因为这个中间人没有ajax
引擎。我们之前说数据在返回到客户端的时候被拦截了,那是谁在拦截啊?是不是ajax
引擎在拦截?那么这个中间人没有ajax
引擎不就不会被拦截了嘛。
那么中间人和客户端之间就更好解释了,ajax
引擎发现客户端在 3000 端口,而且给 3000 端口的中间人发请求,然后这个中间人还从 3000 端口返回数据了,那么这就不跨域了啊,所以就会放行。这就是这个中间人的作用,而这个中间人,就是我们所说的代理。
如何使用代理
我们知道了代理是什么,那么我们现在怎么去使用代理呢?其实这个代理是react
脚手架里的一个比较小的代理服务器,我们怎么去开启这个代理服务器呢?react
脚手架中提供了两种方式,我们先给大家介绍最简单的一种:
{ "name": "react-ajax", "version": "0.1.0", "private": true, "dependencies": {...}, "scripts": {...}, "eslintConfig": {...}, "browserslist": {...}, "proxy": "http://localhost:5000" }
我们先打开项目根目录中的package.json
文件,其他的都不用管,我们来在最下面加一行"proxy": "http://localhost:5000"
,首先proxy
就是代理的意思,当我们加了这一行配置之后,就可以开启我们的代理,之后我们所有发给 3000 端口的请求都会被转发给 5000 端口。但是我们一定要把脚手架停掉,然后再重新启动才能生效。
当我们重启了脚手架之后,我是不是就可以发送请求了?并不是,我们来看我们发送请求时候请求的url
,是不是还是给 5000 端口发的?那不还是一样有跨域问题嘛,那么我们应该给谁发?我们说了代理的端口一定要和客户端端口一致,那么我们是不是要把请求的url
中的端口改成 3000 才行?那么我们现在再试一下效果:
这一次我们是不是成功打印出了我们的数据?
这就是我们react
脚手架中的第一种配置代理的方法
总结
react
本身只关注界面,不包含发送ajax
请求的代码- 前端通过
ajax
请求与后台交互(json
数据) react
应用中需要集成第三方ajax
库(或者自己封装)- 不推荐使用
jQuery
,推荐使用axios
- 通过配置代理解决跨域问题
- 代理端口一定要与客户端端口一致
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/proxy_of_scaffold_1/