React项目与服务端交互

web项目与服务端数据通讯的方法有好多种,这里我们只介绍Restful API的方式。

这里简单说一下接口的定义,因为我们在实际项目中发现有很多都不是很规范。建议大家参考官方资料详细了解,我们举例说明:

定义一个用户的接口: /api/user 这个接口应该具备四个方法:

  • POST 保存用户实体

  • GET 获取用户列表,获取单个用户:/api/user/{userId}

  • PUT 修改用户,与POST区别的是这里在 body 中传的用户实体包含 userId.

  • DELETE 删除用户。尽量不要使用 bodyuserId,部分浏览器不支持。建议使用 /api/user/{userId}

接口返回的数据都为 JSON 格式。

我们一定要将一个服务的所有接口定义一个统一的 URl,以便我们发部后的配置。

我们在介绍 redux-saga 的时候提到了一个 fetchUserApi ,这个方法的实现就是通过接口获取服务端的数据。

接下来介绍两个常用的ajax开源库。

  • axios

    axios 基于Promise的HTTP请求客户端库,在node和浏览器端都可使用。

    官方示例:

    const axios = require('axios');
    // Make a request for a user with a given ID
    axios.get('/user?ID=12345')
      .then(function (response) {
        // handle success
        console.log(response);
      })
      .catch(function (error) {
        // handle error
        console.log(error);
      })
      .then(function () {
        // always executed
      });
    
  • isomorphic-fetch

    isomorphic-fetch,这是一基于 window.fetch 的垫片(polyfill),推荐大家使用这个。

    这里我们简单封装一下:

    import 'es6-promise';
    import fetch from 'isomorphic-fetch';
    
    const checkStatus = (response) => {
      if (response.status >= 200 && response.status < 300) {
        return response;
      }
      const error = new Error(response.statusText);
      error.response = response;
      throw error;
    }
    
    /**
     * Requests a URL, returning a promise.
    *
    * @param  {string} url       The URL we want to request
    * @param  {object} [options] The options we want to pass to "fetch"
    * @return {object}           An object containing either "data" or "err"
    */
    export default request = (url, options) => {
      const defaultOptions = {
        credentials: 'include' //如果不带cookie, 这里可以不用设置
      };
      const newOptions = { ...defaultOptions, ...options };
      if (newOptions.method === 'POST' || newOptions.method === 'PUT') {
        newOptions.headers = {
          Accept: 'application/json',
          'Content-Type': 'application/json; charset=utf-8',
          ...newOptions.headers,
        };
        newOptions.body = JSON.stringify(newOptions.body);
      }
    
      return fetch(url, newOptions)
        .then(checkStatus)
        .then(response => response.json())
        .catch(error => error);
    }
    

    注意,在安装 isomorphic-fetch 时,还需要安装es6-promise,兼容其他一些低版本的浏览器。

有了上面的封装,我们所有接口调用都可以使用了,例如:fetchUserApi

import request from './util/fetch.js'; //上述封装的文件。

export const fetchUserApi = ({userId}) {
  return request(`/api/user/${userId}`, {method: 'GET'});
}

我们大多数据项目都是前后端分离的,也就是服务端接口不在web所运行的环境中,那么想要在 localhost 环境下访问其他 ip 的服务,我们应该配置 webpackproxy

如果你的项目是create-react-app创建的,那么只需要在package.json中配置 proxy,如果有 .webpack.config.js,也可以在这个文件是配置 proxy

示例:

"proxy": {
    "/api": {
       "target": "http://192.168.0.10:8080/"
     }
  }

到此,你的项目就可以完整调用服务端接口了。

results matching ""

    No results matching ""