fetch 详解

作者: 吴佳浩 | 来源:发表于2018-03-15 00:03 被阅读20次

    react - 豆瓣电影案例

    项目中使用的技术点

    • 1 ant-design 组件库
    • 2 react-router-dom 路由
    • 3 fetch API,配合Promise规范
    • 4 跨域获取数据

    ant-design - UI组件库

    • antd
    • 说明:借助 Ant Design 组件库快速搭建页面
    • 安装:npm i -S antd

    基本使用

    • 注意:该步骤中只引入了一个组件,但却引入了整个ant包和css样式
    • 推荐:按需加载,即用到哪个组件就只把该组件的样式导入
    // 基础:导入 react 和 react-dom
    import React from 'react'
    import ReactDOM from 'react-dom'
    
    // 1. 导入 antd 组件
    import { DatePicker } from 'antd'
    
    // 2. 导入 样式
    import 'antd/dist/antd.css'
    
    // 3. 使用 日期选择 组件
    ReactDOM.render(<DatePicker />,
        document.getElementById('app'))
    

    按需加载 - 推荐使用方式

    • 1 安装:npm i -D babel-plugin-import
    • 2 配置.babelrc
    • 说明:只需要导入我们使用的组件即可,不需要再单独的导入样式
    import React from 'react'
    import ReactDOM from 'react-dom'
    
    // 1. 导入 antd 组件
    import { DatePicker } from 'antd'
    
    // 2. 使用 日期选择 组件
    ReactDOM.render(<DatePicker />, document.getElementById('app'))
    
    // ---
    
    // .babelrc 配置如下:
    "plugins": [
        [ "import", { "libraryName": "antd", "style": "css" }]
    ]
    

    react-router

    基本概念说明

    • Router组件本身只是一个容器,真正的路由要通过Route组件定义
    • [图片上传失败...(image-8d092d-1521043307374)]

    使用步骤

    • 1 导入路由组件
    • 2 使用 <Router></Router> 作为根容器,包裹整个应用(JSX)
      • 在整个应用程序中,只需要使用一次
    • 3 使用 <Link to="/movie"></Link> 作为链接地址,并指定to属性
    • 4 使用 <Route path="/" compoent={Movie}></Route> 展示路由内容
    // 1 导入组件
    import {
      HashRouter as Router,
      Link, Route
    } from 'react-router-dom'
    
    // 2 使用 <Router>
    <Router>
    
        // 3 设置 Link
        <Menu.Item key="1"><Link to="/">首页</Link></Menu.Item>
        <Menu.Item key="2"><Link to="/movie">电影</Link></Menu.Item>
        <Menu.Item key="3"><Link to="/about">关于</Link></Menu.Item>
    
        // 4 设置 Route
        // exact 表示:绝对匹配(完全匹配,只匹配:/)
        <Route exact path="/" component={HomeContainer}></Route>
        <Route path="/movie" component={MovieContainer}></Route>
        <Route path="/about" component={AboutContainer}></Route>
    
    </Router>
    

    注意点

    • <Router></Router>:作为整个组件的根元素,是路由容器,只能有一个唯一的子元素
    • <Link></Link>:类似于vue中的<router-link></router-link>标签,to 属性指定路由地址
    • <Route></Route>:类似于vue中的<router-view></router-view>,指定路由内容(组件)展示位置

    路由参数

    • 配置:通过Route中的path属性来配置路由参数
    • 获取:this.props.match.params 获取
    // 配置路由参数
    <Route path="/movie/:movieType"></Route>
    
    // 获取路由参数
    const type = this.props.match.params.movieType
    

    路由跳转

    • react router - history
    • history.push() 方法用于在JS中实现页面跳转
    • history.go(-1) 用来实现页面的前进(1)和后退(-1)
    this.props.history.push('/movie/movieDetail/' + movieId)
    

    fetch

    • 作用:Fetch 是一个现代的概念, 等同于 XMLHttpRequest。它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性。
    • fetch() 方法返回一个Promise对象

    fetch 基本使用

    /*
      通过fetch请求回来的数据,是一个Promise对象.
      调用then()方法,通过参数response,获取到响应对象
      调用 response.json() 方法,解析服务器响应数据
      再次调用then()方法,通过参数data,就获取到数据了
    */
    fetch('/api/movie/' + this.state.movieType)
      // response.json() 读取response对象,并返回一个被解析为JSON格式的promise对象
      .then((response) => response.json())
      // 通过 data 获取到数据
      .then((data) => {
        console.log(data);
        this.setState({
          movieList: data.subjects,
          loaing: false
        })
      })
    

    跨域获取数据的三种常用方式

    • 1 JSONP
    • 2 代理
    • 3 CORS

    JSONP

    • 安装:npm i -S fetch-jsonp
    • 利用JSONP实现跨域获取数据,只能获取GET请求
    • fetch-jsonp
    • fetch-jsonp
    • 限制:1 只能发送GET请求 2 需要服务端支持JSONP请求
    /* movielist.js */
    fetchJsonp('https://api.douban.com/v2/movie/in_theaters')
      .then(rep => rep.json())
      .then(data => { console.log(data) })
    

    代理

    • webpack-dev-server 代理配置如下:
    • 问题:webpack-dev-server 是开发期间使用的工具,项目上线了就不再使用 webpack-dev-server
    • 解决:项目上线后的代码,也是会部署到一个服务器中,这个服务器配置了代理功能即可(要求两个服务器中配置的代理规则相同)
    // webpack-dev-server的配置
    devServer: {
      // https://webpack.js.org/configuration/dev-server/#devserver-proxy
      // https://github.com/chimurai/http-proxy-middleware#http-proxy-options
      // http://www.jianshu.com/p/3bdff821f859
      proxy: {
        // 使用:/api/movie/in_theaters
        // 访问 ‘/api/movie/in_theaters’ ==> 'https://api.douban.com/v2/movie/in_theaters'
        '/api': {
          // 代理的目标服务器地址
          target: 'https://api.douban.com/v2',
          // https请求需要该设置
          secure: false,
          // 必须设置该项
          changeOrigin: true,
          // '/api/movie/in_theaters' 路径重写为:'/movie/in_theaters'
          pathRewrite: {"^/api" : ""}
        }
      }
    }
    
    /* movielist.js */
    fetch('/api/movie/in_theaters')
      .then(function(data) {
        // 将服务器返回的数据转化为 json 格式
        return data.json()
      })
      .then(function(rep) {
        // 获取上面格式化后的数据
        console.log(rep);
      })
    

    CORS - 服务器端配合

    // 通过Express的中间件来处理所有请求
    app.use(function (req, res, next) {
      // 设置响应头为允许跨域
      res.header('Access-Control-Allow-Origin', '*');
    
      // 设置服务器支持的所有头信息字段
      res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization,Accept,X-Requested-With');
      // 设置服务器支持的所有跨域请求的方法
      res.header('Access-Control-Allow-Methods', 'POST,GET');
      // next()方法表示进入下一个路由
      next();
    });
    

    相关文章

      网友评论

        本文标题:fetch 详解

        本文链接:https://www.haomeiwen.com/subject/flugfftx.html