• [尚硅谷React笔记]——第4章 React ajax


    目录:

    1. 脚手架配置代理_方法一
      1. server1.js
      2. 开启服务器server1:
      3. App.js
      4. 解决跨域问题:
    2. 脚手架配置代理_方法二
      1. ​​​​​​​server2.js
      2. 开启服务器server2
      3. 第一步:创建代理配置文件
      4. 编写setupProxy.js配置具体代理规则:
      5. App.js
      6. 运行结果:
      7. 说明:
    3. github用户搜索案例
      1. github搜索案例_静态组件
      2. github搜索案例_axios发送请求
      3. github搜索案例_展示数据
      4. github搜索案例_完成案例
    4. 消息订阅与发布_pubsub
    5. fetch发送请求

    1.脚手架配置代理_方法一

    server1.js
    1. const express = require('express')
    2. const app = express()
    3. app.use((request,response,next)=>{
    4. console.log('有人请求服务器1了');
    5. console.log('请求来自于',request.get('Host'));
    6. console.log('请求的地址',request.url);
    7. next()
    8. })
    9. app.get('/students',(request,response)=>{
    10. const students = [
    11. {id:'001',name:'tom',age:18},
    12. {id:'002',name:'jerry',age:19},
    13. {id:'003',name:'tony',age:120},
    14. ]
    15. response.send(students)
    16. })
    17. app.listen(5000,(err)=>{
    18. if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');
    19. })
    开启服务器server1:

    App.js
    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. class App extends Component {
    4. getStudentData = () => {
    5. axios.get('http://localhost:5000/students').then(
    6. response => {
    7. console.log('成功了', response.data);
    8. },
    9. error => {
    10. console.log('失败了', error);
    11. }
    12. )
    13. }
    14. render() {
    15. return (
  • );
  • }
  • }
  • export default App;
  • 解决跨域问题:

    package.json

    1. {
    2. "name": "20231003",
    3. "version": "0.1.0",
    4. "private": true,
    5. "dependencies": {
    6. "@testing-library/jest-dom": "^5.17.0",
    7. "@testing-library/react": "^13.4.0",
    8. "@testing-library/user-event": "^13.5.0",
    9. "axios": "^1.5.1",
    10. "nanoid": "^5.0.1",
    11. "prop-types": "^15.8.1",
    12. "react": "^18.2.0",
    13. "react-dom": "^18.2.0",
    14. "react-scripts": "5.0.1",
    15. "web-vitals": "^2.1.4"
    16. },
    17. "scripts": {
    18. "start": "react-scripts start",
    19. "build": "react-scripts build",
    20. "test": "react-scripts test",
    21. "eject": "react-scripts eject"
    22. },
    23. "eslintConfig": {
    24. "extends": [
    25. "react-app",
    26. "react-app/jest"
    27. ]
    28. },
    29. "browserslist": {
    30. "production": [
    31. ">0.2%",
    32. "not dead",
    33. "not op_mini all"
    34. ],
    35. "development": [
    36. "last 1 chrome version",
    37. "last 1 firefox version",
    38. "last 1 safari version"
    39. ],
    40. "proxy": "http://localhost:5000"
    41. }
    42. }

    使用方法一遇到了bug,去stackoverflow解决一下,能解决,但是有更好的方法,方法一不在继续了.node.js - Invalid options object. Dev Server has been initialized using an options object that does not match the API schema - Stack Overflow

    2.脚手架配置代理_方法二

    server2.js
    1. const express = require('express')
    2. const app = express()
    3. app.use((request,response,next)=>{
    4. console.log('有人请求服务器2了');
    5. next()
    6. })
    7. app.get('/cars',(request,response)=>{
    8. const cars = [
    9. {id:'001',name:'奔驰',price:199},
    10. {id:'002',name:'马自达',price:109},
    11. {id:'003',name:'捷达',price:120},
    12. ]
    13. response.send(cars)
    14. })
    15. app.listen(5001,(err)=>{
    16. if(!err) console.log('服务器2启动成功了,请求汽车信息地址为:http://localhost:5001/cars');
    17. })
    开启服务器server2

    访问端口:

    第一步:创建代理配置文件

    在src下创建配置文件:src/setupProxy.js

    编写setupProxy.js配置具体代理规则:

    这个适合低版本

    const proxy = require('http-proxy-middleware')

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

    我使用的node是:v18.18.0 

    //react 18版本写法
    const {createProxyMiddleware} = require('http-proxy-middleware')
    
    module.exports = function (app) {
        app.use(
            createProxyMiddleware('/api1', {
                target: 'http://localhost:5000',
                changeOrigin: true,
                pathRewrite: {'^/api1': ''}
            }),
            createProxyMiddleware('/api2', {
                target: 'http://localhost:5001',
                changeOrigin: true,
                pathRewrite: {'^/api2': ''}
            }),
        )
    }
    
    App.js 
    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. class App extends Component {
    4. getStudentData = () => {
    5. axios.get('http://localhost:3000/api1/students').then(
    6. response => {
    7. console.log('成功了', response.data);
    8. },
    9. error => {
    10. console.log('失败了', error);
    11. }
    12. )
    13. }
    14. getCarData = () => {
    15. axios.get('http://localhost:3000/api2/cars').then(
    16. response => {
    17. console.log('成功了', response.data);
    18. },
    19. error => {
    20. console.log('失败了', error);
    21. }
    22. )
    23. }
    24. render() {
    25. return (
  • );
  • }
  • }
  • export default App;
  • 运行结果:

    说明:
    1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。

    2. 缺点:配置繁琐,前端请求资源时必须加前缀。

    3.github用户搜索案例

    github搜索案例_静态组件

    App.js

    1. import React, {Component} from 'react';
    2. import Search from './components/Search/Search'
    3. import List from "./components/List/List";
    4. class App extends Component {
    5. render() {
    6. return (
    7. "container">
  • );
  • }
  • }
  • export default App;
  • index.js

    1. import React from 'react';
    2. import ReactDOM from 'react-dom/client';
    3. import App from './App';
    4. const root = ReactDOM.createRoot(document.getElementById('root'));
    5. root.render();

     List.jsx

    1. import React, {Component} from 'react';
    2. import './List.css'
    3. class List extends Component {
    4. render() {
    5. return (
    6. "row">
    7. "card">
    8. "card-text">reactjs

    9. );
    10. }
    11. }
    12. export default List;

     List.css

    1. .album {
    2. min-height: 50rem; /* Can be removed; just added for demo purposes */
    3. padding-top: 3rem;
    4. padding-bottom: 3rem;
    5. background-color: #f7f7f7;
    6. }
    7. .card {
    8. float: left;
    9. width: 33.333%;
    10. padding: .75rem;
    11. margin-bottom: 2rem;
    12. border: 1px solid #efefef;
    13. text-align: center;
    14. }
    15. .card > img {
    16. margin-bottom: .75rem;
    17. border-radius: 100px;
    18. }
    19. .card-text {
    20. font-size: 85%;
    21. }

    Search.jsx

    1. import React, {Component} from 'react';
    2. class Search extends Component {
    3. render() {
    4. return (
    5. "jumbotron">
    6. "jumbotron-heading">Search Github Users

    7. type="text" placeholder="enter the name you search"/> 
    8. );
    9. }
    10. }
    11. export default Search;

    运行结果:

     

    github搜索案例_axios发送请求

    demo.html

    1. "en">
    2. <head>
    3. "UTF-8">
    4. Title

    server.js

    1. const express = require("express")
    2. const axios = require("axios")
    3. const app = express()
    4. /*
    5. 请求地址: http://localhost:3000/search/users?q=aa
    6. 后台路由
    7. key: /search/users
    8. value: function () {}
    9. */
    10. app.get("/search/users", function (req, res) {
    11. const {q} = req.query
    12. axios({
    13. url: 'https://api.github.com/search/users',
    14. params: {q}
    15. }).then(response => {
    16. res.json(response.data)
    17. })
    18. })
    19. app.get("/search/users2", function (req, res) {
    20. res.json({
    21. items: [
    22. {
    23. login: "yyx990803",
    24. html_url: "https://github.com/yyx990803",
    25. avatar_url:
    26. "https://avatars3.githubusercontent.com/u/499550?s=460&u=de41ec9325e8a92e281b96a1514a0fd1cd81ad4a&v=4",
    27. id: 1,
    28. },
    29. {
    30. login: "ruanyf",
    31. html_url: "https://github.com/ruanyf",
    32. avatar_url: "https://avatars2.githubusercontent.com/u/905434?s=460&v=4",
    33. id: 2,
    34. },
    35. {
    36. login: "yyx9908032",
    37. html_url: "https://github.com/yyx990803",
    38. avatar_url:
    39. "https://avatars3.githubusercontent.com/u/499550?s=460&u=de41ec9325e8a92e281b96a1514a0fd1cd81ad4a&v=4",
    40. id: 3,
    41. },
    42. {
    43. login: "ruanyf2",
    44. html_url: "https://github.com/ruanyf",
    45. avatar_url: "https://avatars2.githubusercontent.com/u/905434?s=460&v=4",
    46. id: 4,
    47. },
    48. {
    49. login: "yyx9908033",
    50. html_url: "https://github.com/yyx990803",
    51. avatar_url:
    52. "https://avatars3.githubusercontent.com/u/499550?s=460&u=de41ec9325e8a92e281b96a1514a0fd1cd81ad4a&v=4",
    53. id: 5,
    54. },
    55. {
    56. login: "ruanyf3",
    57. html_url: "https://github.com/ruanyf",
    58. avatar_url: "https://avatars2.githubusercontent.com/u/905434?s=460&v=4",
    59. id: 6,
    60. },
    61. {
    62. login: "yyx9908034",
    63. html_url: "https://github.com/yyx990803",
    64. avatar_url:
    65. "https://avatars3.githubusercontent.com/u/499550?s=460&u=de41ec9325e8a92e281b96a1514a0fd1cd81ad4a&v=4",
    66. id: 7,
    67. },
    68. {
    69. login: "ruanyf4",
    70. html_url: "https://github.com/ruanyf",
    71. avatar_url: "https://avatars2.githubusercontent.com/u/905434?s=460&v=4",
    72. id: 8,
    73. },
    74. {
    75. login: "yyx9908035",
    76. html_url: "https://github.com/yyx990803",
    77. avatar_url:
    78. "https://avatars3.githubusercontent.com/u/499550?s=460&u=de41ec9325e8a92e281b96a1514a0fd1cd81ad4a&v=4",
    79. id: 9,
    80. },
    81. ],
    82. });
    83. });
    84. app.listen(5000, "localhost", (err) => {
    85. if (!err){
    86. console.log("服务器启动成功")
    87. console.log("请求github真实数据请访问:http://localhost:5000/search/users")
    88. console.log("请求本地模拟数据请访问:http://localhost:5000/search/users2")
    89. }
    90. else console.log(err);
    91. })

    启动服务器:

    node .\server.js
    

     App.js

    1. import React, {Component} from 'react';
    2. import Search from './components/Search/Search'
    3. import List from "./components/List/List";
    4. class App extends Component {
    5. render() {
    6. return (
    7. "container">
    8. );
    9. }
    10. }
    11. export default App;

    index.js

    1. import React from 'react';
    2. import ReactDOM from 'react-dom/client';
    3. import App from './App';
    4. const root = ReactDOM.createRoot(document.getElementById('root'));
    5. root.render();

    List.jsx

    1. import React, {Component} from 'react';
    2. import './List.css'
    3. class List extends Component {
    4. render() {
    5. return (
    6. "row">
    7. "card">
    8. "card-text">reactjs

    9. );
    10. }
    11. }
    12. export default List;

    List.css

    1. .album {
    2. min-height: 50rem; /* Can be removed; just added for demo purposes */
    3. padding-top: 3rem;
    4. padding-bottom: 3rem;
    5. background-color: #f7f7f7;
    6. }
    7. .card {
    8. float: left;
    9. width: 33.333%;
    10. padding: .75rem;
    11. margin-bottom: 2rem;
    12. border: 1px solid #efefef;
    13. text-align: center;
    14. }
    15. .card > img {
    16. margin-bottom: .75rem;
    17. border-radius: 100px;
    18. }
    19. .card-text {
    20. font-size: 85%;
    21. }

    Search.jsx

    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. class Search extends Component {
    4. search = () => {
    5. //连续结构+重命名
    6. const {keyWordElement: {value: keyWord}} = this
    7. axios.get(`http://localhost:3000/api1/search/users2?q=${keyWord}`).then(
    8. response => {
    9. console.log('成功了', response.data);
    10. },
    11. error => {
    12. console.log('失败了', error);
    13. }
    14. )
    15. }
    16. render() {
    17. return (
    18. "jumbotron">
    19. "jumbotron-heading">搜索github用户

    20. this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> 
    21. );
    22. }
    23. }
    24. export default Search;

     setupProxy.js

    1. //react 18版本写法
    2. const {createProxyMiddleware} = require('http-proxy-middleware')
    3. module.exports = function (app) {
    4. app.use(
    5. createProxyMiddleware('/api1', {
    6. target: 'http://localhost:5000',
    7. changeOrigin: true,
    8. pathRewrite: {'^/api1': ''}
    9. }),
    10. )
    11. }

     

    运行结果:

     

    github搜索案例_展示数据

    App.js

    1. import React, {Component} from 'react';
    2. import Search from './components/Search/Search'
    3. import List from "./components/List/List";
    4. class App extends Component {
    5. state = {users: []}
    6. saveUsers = (users) => {
    7. this.setState({users})
    8. }
    9. render() {
    10. const {users} = this.state
    11. return (
    12. "container">
    13. users={users}>
    14. );
    15. }
    16. }
    17. export default App;

    List.jsx

    1. import React, {Component} from 'react';
    2. import './List.css'
    3. class List extends Component {
    4. render() {
    5. return (
    6. "row">
    7. {
    8. this.props.users.map((userObj) => {
    9. return (
    10. {userObj.login}

    11. )
    12. })
    13. }
    14. );
    15. }
    16. }
    17. export default List;

     Search.jsx

    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. class Search extends Component {
    4. search = () => {
    5. //连续结构+重命名
    6. const {keyWordElement: {value: keyWord}} = this
    7. axios.get(`http://localhost:3000/api1/search/users2?q=${keyWord}`).then(
    8. response => {
    9. console.log('成功了', response.data.items);
    10. this.props.saveUsers(response.data.items)
    11. },
    12. error => {
    13. console.log('失败了', error);
    14. }
    15. )
    16. }
    17. render() {
    18. return (
    19. "jumbotron">
    20. "jumbotron-heading">搜索github用户

    21. this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> 
    22. );
    23. }
    24. }
    25. export default Search;

    运行结果:

    github搜索案例_完成案例

    App.js

    1. import React, {Component} from 'react';
    2. import Search from './components/Search/Search'
    3. import List from "./components/List/List";
    4. class App extends Component {
    5. state = {users: [], isFirst: true, isLoading: false, err: ''}
    6. saveUsers = (users) => {
    7. this.setState({users})
    8. }
    9. updateAppState = (stateObj) => {
    10. this.setState(stateObj)
    11. }
    12. render() {
    13. const {users} = this.state
    14. return (
    15. "container">
    16. );
    17. }
    18. }
    19. export default App;

    Search.jsx

    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. class Search extends Component {
    4. search = () => {
    5. //连续结构+重命名
    6. const {keyWordElement: {value: keyWord}} = this
    7. console.log(keyWord)
    8. this.props.updateAppState({isFirst: false, isLoading: true})
    9. axios.get(`http://localhost:3000/api1/search/users2?q=${keyWord}`).then(
    10. response => {
    11. console.log('成功了', response.data.items);
    12. this.props.updateAppState({isLoading: false, users: response.data.items})
    13. },
    14. error => {
    15. console.log('失败了', error);
    16. this.props.updateAppState({isLoading: false, err: error.message})
    17. }
    18. )
    19. }
    20. render() {
    21. return (
    22. "jumbotron">
    23. "jumbotron-heading">搜索github用户

    24. this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> 
    25. );
    26. }
    27. }
    28. export default Search;

    List.jsx

    1. import React, {Component} from 'react';
    2. import './List.css'
    3. class List extends Component {
    4. render() {
    5. const {users, isFirst, isLoading, err} = this.props
    6. return (
    7. "row">
    8. {
    9. isFirst ?

      欢迎使用,输入关键字,然后点击搜索

      :
    10. isLoading ?

      加载中...

      :
    11. err ?

      'red'}}>{err}

      :
    12. users.map((userObj) => {
    13. return (
    14. {userObj.login}

    15. )
    16. })
    17. }
    18. );
    19. }
    20. }
    21. export default List;

     setProxy.js

    1. //react 18版本写法
    2. const {createProxyMiddleware} = require('http-proxy-middleware')
    3. module.exports = function (app) {
    4. app.use(
    5. createProxyMiddleware('/api1', {
    6. target: 'http://localhost:5000',
    7. changeOrigin: true,
    8. pathRewrite: {'^/api1': ''}
    9. }),
    10. )
    11. }

    index.js

    1. import React from 'react';
    2. import ReactDOM from 'react-dom/client';
    3. import App from './App';
    4. const root = ReactDOM.createRoot(document.getElementById('root'));
    5. root.render();

    运行结果:

    4.消息订阅与发布_pubsub

    App.js

    1. import React, {Component} from 'react';
    2. import Search from './components/Search/Search'
    3. import List from "./components/List/List";
    4. class App extends Component {
    5. render() {
    6. return (
    7. "container">
    8. );
    9. }
    10. }
    11. export default App;

    List.jsx

    1. import React, {Component} from 'react';
    2. import './List.css'
    3. import PubSub from 'pubsub-js'
    4. class List extends Component {
    5. state = {users: [], isFirst: true, isLoading: false, err: ''}
    6. componentDidMount() {
    7. this.token = PubSub.subscribe('atguigu', (_, stateObj) => {
    8. console.log(stateObj);
    9. this.setState(stateObj);
    10. })
    11. }
    12. componentWillUnmount() {
    13. PubSub.unsubscribe(this.token)
    14. }
    15. render() {
    16. const {users, isFirst, isLoading, err} = this.state
    17. return (
    18. "row">
    19. {
    20. isFirst ?

      欢迎使用,输入关键字,然后点击搜索

      :
    21. isLoading ?

      加载中...

      :
    22. err ?

      'red'}}>{err}

      :
    23. users.map((userObj) => {
    24. return (
    25. {userObj.login}

    26. )
    27. })
    28. }
    29. );
    30. }
    31. }
    32. export default List;

     Search.jsx

    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. import PubSub from "pubsub-js";
    4. class Search extends Component {
    5. search = () => {
    6. //连续结构+重命名
    7. const {keyWordElement: {value: keyWord}} = this
    8. console.log(keyWord)
    9. // this.props.updateAppState({isFirst: false, isLoading: true})
    10. PubSub.publish('atguigu', {isFirst: false, isLoading: true})
    11. axios.get(`http://localhost:3000/api1/search/users2?q=${keyWord}`).then(
    12. response => {
    13. console.log('成功了', response.data.items);
    14. // this.props.updateAppState({isLoading: false, users: response.data.items})
    15. PubSub.publish('atguigu', {isLoading: false, users: response.data.items})
    16. },
    17. error => {
    18. console.log('失败了', error);
    19. // this.props.updateAppState({isLoading: false, err: error.message})
    20. PubSub.publish('atguigu', {isLoading: false, err: error.message})
    21. }
    22. )
    23. }
    24. render() {
    25. return (
    26. "jumbotron">
    27. "jumbotron-heading">搜索github用户

    28. this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> 
    29. );
    30. }
    31. }
    32. export default Search;

    setupProxy.js

    1. //react 18版本写法
    2. const {createProxyMiddleware} = require('http-proxy-middleware')
    3. module.exports = function (app) {
    4. app.use(
    5. createProxyMiddleware('/api1', {
    6. target: 'http://localhost:5000',
    7. changeOrigin: true,
    8. pathRewrite: {'^/api1': ''}
    9. })
    10. )
    11. }

    运行结果:

    5.fetch发送请求

    Search.jsx

    1. import React, {Component} from 'react';
    2. import axios from "axios";
    3. import PubSub from "pubsub-js";
    4. class Search extends Component {
    5. search = async () => {
    6. //连续结构+重命名
    7. const {keyWordElement: {value: keyWord}} = this
    8. PubSub.publish('atguigu', {isFirst: false, isLoading: true})
    9. try {
    10. const response = await fetch(`http://localhost:3000/api1/search/users2?q=${keyWord}`)
    11. const data = await response.json()
    12. console.log(data)
    13. PubSub.publish('atguigu', {isLoading: false, users: data.items})
    14. } catch (error) {
    15. console.log('请求出错', error)
    16. PubSub.publish('atguigu', {isLoading: false, err: error.message})
    17. }
    18. }
    19. render() {
    20. return (
    21. "jumbotron">
    22. "jumbotron-heading">搜索github用户

    23. this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> 
    24. );
    25. }
    26. }
    27. export default Search;

    ajax,fetch,xhr,axios,jquery之间的关系 

     

    运行结果:

  • 相关阅读:
    Apache ShardingSphere(一) 基本概念介绍
    【数据聚类】第七章第一节:半监督聚类算法概述
    【鸿蒙软件开发】ArkTS基础组件之Select(下拉菜单)、Slider(滑动条)
    高级前端手写面试题
    关于影响编码效果的画质调优总结
    「Python入门」Python多进程
    UE5 里的一些常用的了解
    503. 下一个更大元素 II
    Mac安装多个版本Node.js
    汽车电子专业知识篇(六十一)-特斯拉Model 3的BMS系统
  • 原文地址:https://blog.csdn.net/qq_56444564/article/details/133619648