4_React ajax

文章目录

1、理解
2、axios
3、消息订阅-发布机制
4、拓展:Fetch

一、理解

1、前置说明

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

2、常用的ajax请求库

  • jQuery:比较重,若需要另外引用,不建议用
  • axios:轻量级,建议使用。
    1. 封装XmlHttpRequest对象的ajax
    2. promise风格
    3. 可以用在浏览器端和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’ 跨域错误

其中,请求是有发送出去的,只是无法接收到请求结果
4_React ajax_第1张图片

// 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个要求

  1. 使用下列方法之一:GET、HEAD、POST
  2. 只使用了如下的安全 Header:Accept、Accept-Language、Content-Language、Content-Type 的值仅限于这三者之一(text/plain、multipart/form-data、application/x-www-form-urlencoded),不得人为设置其他 Header
  3. 请求中的任意 XMLHttpRequest 对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问。
  4. 请求中没有使用 ReadableStream 对象。

三、消息订阅-发布机制

兄弟组件间通信

正常写法: 需借助父组件,把需通信的状态存放在父组件。父组件通过props传给子组件A:一个函数,子组件A通过调用此函数将变化传给父组件,父组件再把对应的值传给子组件B。这样就完成了兄弟组件间的通信。

订阅消息: 1、消息名; 2、发布消息

适用于任意组件的沟通

  1. 工具库:PubSubJS
  2. 下载:npm install pubsub-js -save
  3. 使用:
    • 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)
})

你可能感兴趣的:(react,ajax,react.js,javascript)