文章目录
1、理解
2、axios
3、消息订阅-发布机制
4、拓展:Fetch
一、理解
1、前置说明
- React本身只关注于界面,并不包含发送ajax请求的代码
- 前端应用需要通过ajax请求与后台进行交互
- react库需要集成第三方ajax库(或自己封装)
2、常用的ajax请求库
- jQuery:比较重,若需要另外引用,不建议用
- axios:轻量级,建议使用。
- 封装XmlHttpRequest对象的ajax
- promise风格
- 可以用在浏览器端和node服务端
二、axios
1、文档
https://github.com/axios/axios
2、测试代理服务器(Node.js + express)
谷歌插件:feHelper
,用于整理JSON数据
const express = require('express')
const app = express()
app.use((request,response,next)=>{
console.log('有人请求服务器1了');
console.log('请求来自于',request.get('Host'));
console.log('请求的地址',request.url);
console.log('查询参数', request.query);
console.log('路由参数', request.params);
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)
})
app.listen(5000,(err)=>{
if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');
})
3、相关API
- GET请求
axios.get('/user?id=123456')
.then(function(res){
console.log(res.data)
})
.catch(function(err){
console.log(err)
})
axios.get('/user', {
params: {
id: 123456
}
})
.then(function(res){
console.log(res.data)
})
.catch(function(err){
console.log(err)
})
- POST请求
axios.post('/user', {
firstName: '小一',
lastName: '小二'
})
.then(function(res){
console.log(res.data)
})
.catch(function(err){
console.log(err)
})
4、No ‘Access-Control-Allow-Origin’ 跨域错误
其中,请求是有发送出去的,只是无法接收到请求结果
// setupProxy.js
const proxy = require('http-proxy-middleware'); // react脚手架里已下载
module.exports = function(app){
app.use(
proxy('/api1', { // 遇见/api1前缀的请求,就会触发该代理
target: 'http://localhost:5000', // 请求转发给谁
changeOrigin: true, // 默认值为false,控制服务器接收到的请求头中Host的值,true: 'localhost:5000', false: 'localhost:3000'。一般设置为true
pathRewrite: {'^/api1': ''} // 重写请求路径,必须配置,保证交给服务器的是正常请求地址
proxy('/api2', {
target: 'http://localhost:5001',
changeOrigin: true, // 默认值为false
pathRewrite: {'^/api2': ''}
})
)
}
// 配置完,必须重新启动
// 请求路径有/api1前缀,如:http://localhost:3000/api1/...,会走代理服务器http://localhost:5000
// 请求路径有/api2前缀,如:http://localhost:3000/api2/...,会走代理服务器http://localhost:5001
github服务器为何未产生跨域?
答:后端解决跨域一劳永逸的方法,cors解决跨域,只需要加上一种特殊的响应头
跨域的请求在服务端会不会真正执行?
- 跨域的请求有的时候执行,有的时候不执行。
- 简单请求的情况下,不管是否跨域,一定会到达服务端并被执行,浏览器会隐藏返回值
- 复杂请求的情况下,先发预检请求,预检请求不会真正执行业务逻辑,预检请求通过后才会发送真正请求并在服务端执行
简单请求: 满足下列4个要求
- 使用下列方法之一:GET、HEAD、POST
- 只使用了如下的安全 Header:Accept、Accept-Language、Content-Language、Content-Type 的值仅限于这三者之一(text/plain、multipart/form-data、application/x-www-form-urlencoded),不得人为设置其他 Header
- 请求中的任意 XMLHttpRequest 对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问。
- 请求中没有使用 ReadableStream 对象。
三、消息订阅-发布机制
兄弟组件间通信
正常写法: 需借助父组件,把需通信的状态存放在父组件。父组件通过props传给子组件A:一个函数,子组件A通过调用此函数将变化传给父组件,父组件再把对应的值传给子组件B。这样就完成了兄弟组件间的通信。
订阅消息: 1、消息名; 2、发布消息
适用于任意组件的沟通
- 工具库:PubSubJS
- 下载:npm install pubsub-js -save
- 使用:
- import PubSub from ‘pubsub-js’ // 引入
- this.token = PubSub.subscribe(‘delete’, function(msg, data){}); // 订阅
- PubSub.publish(‘delete’, data); // 发布
- PubSub.unsubscrible(this.token); // 取消订阅
四、拓展:Fetch
通过xhr,延伸出了jQuery、axios(promise封装)
fetch,原生函数,也是promise封装的,浏览器可直接用,无需再引入,关注分离
。兼容性不是很高。
1、文档
https://github.github.io/fetch/
https://segmentfault.com/a/1190000003810652
2、特点
原生函数
,不再使用XmlHttpRequest对象提交ajax请求- 老版本浏览器可能不支持
3、相关API
- GET请求
fetch(url).then(function(res){
// 是否成功联系服务器
return res.json();
}).then(function(data){
// 请求成功
console.log(data)
}).catch(function(err){
// 请求报错
console.log(err)
})
- POST请求
fetch(url,{
method:'POST',
body:JSON.stringfy(data)
}).then(function(data){
console.log(data)
}).catch(function(err){
console.log(err)
})