Web 使用fetch请求后端服务

前端开发 简书

上篇我们使用了ssm构建了我们简历的服务, 这篇我们从前端的视角进行网络请求, 对于react就要讲讲fetch这个库的使用, 对于vue就要讲讲axios这个库, 对于axios之前已经讲过, 这篇就来讲讲fetch的使用.

参考链接:

以下内容在上述文章基础上进行, 请事先查阅.

安装fetch

当然说到fetch, 其实就是对于ajax的一个封装, 类似于iOS的AFNetworking, 首先我们先从npm 加载这个库.

$ npm instaill fetch --save

在开始进行网络请求之前, 我们需要和后端定义好接口以及返回的数据, 当然如果是前后端一起开发的话, 就没有这个困扰了.

查阅fetch文档

文档链接

Usage synopsis (use the argument links to find out more):

fetch(url, options).then(function(response) {
  // handle HTTP response
}, function(error) {
  // handle network error
})
More comprehensive usage example:

fetch(url, {
  method: "POST",
  body: JSON.stringify(data),
  headers: {
    "Content-Type": "application/json"
  },
  credentials: "same-origin"
}).then(function(response) {
  response.status     //=> number 100–599
  response.statusText //=> String
  response.headers    //=> Headers
  response.url        //=> String

  return response.text()
}, function(error) {
  error.message //=> String
})

自行封装fetch

像我们在iOS中使用第三方库的时候回在其基础上封装一层, 以便日后维护方便, 对于前端, 设计思想也是一样的, 我们就来新建一个http.js来封装网络请求和接口.

const host = 'http://localhost:8080';

export function GET(url) {
    var fetchOptions = {
        method: 'GET'
    };
    return new Promise((resolve, reject) => {
        fetch(url, fetchOptions).then(response => response.json()).then(response => resolve(response.data)).catch((error) => {
            reject(error);
        })
    });
}

export const URL = {
    fetchProfile: `${host}/portal/fetch_profile.do`,
    fetchProjects: `${host}/portal/fetch_projects.do`,
    fetchGitHub: `${host}/portal/fetch_github.do`,
    fetchArticles: `${host}/portal/fetch_articles.do`,
    fetchExperience: `${host}/portal/fetch_experience.do`,
    fetchContact: `${host}/portal/fetch_contact.do`
}

非常简单的在fetch的基础上使用Promise进行封装, 并将所需要的接口整合到一起以便日后的维护.

查看接口

为例完成下图的展示, 我们已经通过ssm写好了这个接口.

我们就以第一个接口举例 fetchProfile:
${host}/portal/fetch_profile.do`,如果你对es6模板字符串的语法不熟悉的话, 可以自行搜索下, 我们先来看看这个接口的返回.

/* http://localhost:8080/portal/fetch_profile.do */
{
    "status": 0,
    "data": {
        "profileImage": "http://upload-images.jianshu.io/upload_images/1229762-23e162b9bd6b9c39.JPG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
        "profileName": "Shuangquan Zhu",
        "profileCareer": "Designer / Developer",
        "profileLocation": "Shanghai",
        "profileSocialList": [
            {
                "src": "http://upload-images.jianshu.io/upload_images/1229762-877e3e5c2260bcf1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
                "href": "https://github.com/coderzsq"
            },
            {
                "src": "http://upload-images.jianshu.io/upload_images/1229762-f6525252f3e8387b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
                "href": "http://www.jianshu.com/u/9d7fad1a4693"
            },
            {
                "src": "http://upload-images.jianshu.io/upload_images/1229762-a69614a97de93f36.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
                "href": "http://upload-images.jianshu.io/upload_images/1229762-453920a3f4eedcd8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"
            },
            {
                "src": "http://upload-images.jianshu.io/upload_images/1229762-91b0949aec719aab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
                "href": "http://coderzsq.github.io/"
            }
        ],
        "profileSummaryTitle": "Summary",
        "profileSummaryDescription": "Shuangquan Zhu is a professional developer who focuses on iOS now. He has strong knowledge of Objective-C, Swift and Javascript. With these skills, he created quite a few quickly developer tools. He also leads the J1 iOS team to promote the project process.\nHe crazy loves playing basketball with friends in spare time, He also loves traveling, writing and listening music. He is always willing to try new things, and keeping to learn from them.",
        "profileInterestTitle": "Interest",
        "profileInterestList": [
            {
                "interest": "Learn about high tech"
            },
            {
                "interest": "Play basketball"
            },
            {
                "interest": "Listen to music"
            },
            {
                "interest": "Apple products"
            }
        ],
        "profileEducationTitle": "Education",
        "profileEducationList": [
            {
                "major": "Business Management",
                "school": "East China University of Science and Technology",
                "year": "2016"
            },
            {
                "major": "Customs and International Freight",
                "school": "Shanghai Maritime Academy",
                "year": "2013"
            }
        ]
    }
}

这个返回的数据结构已经可以完美匹配上图的数据展示需求了.

如何请求

就以第一个模块举例, 我们打开 pc_home.js
为例:

构造函数

constructor() {
        super();
        this.state = {
            data: {
                profileImage: '',
                profileName: '',
                profileCareer: '',
                profileLocation: '',
                profileSocialList: [],
                profileSummaryTitle: '',
                profileSummaryDescription: '',
                profileInterestTitle: '',
                profileInterestList: [],
                profileEducationTitle: '',
                profileEducationList: []
            }
        }
    }

首先我们需要添加构造函数, 字段对应返回的数据结构.

生命周期函数

componentWillMount() {
        GET(URL.fetchProfile).then((data) => {
            this.setState({data: data})
        })
    }

生命周期函数, 用于页面的请求, 我们可以看到对刚才fetch封装类的调用.

渲染函数

render() {
        const {data} = this.state;
        let profileLocation = data.profileLocation.length ? `Location: ${data.profileLocation}` : ''
        let profileSummaryDescription = data.profileSummaryDescription.split('\n').map((description, index) => (
            

{description}

)) let profileSocialList = data.profileSocialList.map((socialVo, index) => (
)) let profileInterestList = data.profileInterestList.map((interestVo, index) => (
  • # {interestVo.interest}
  • )) let profileEducationList = data.profileEducationList.map((educationVo, index) => (
    {educationVo.major} - {educationVo.year}
    {educationVo.school}
    )) return (
    {data.profileName}
    {data.profileCareer}
    {profileLocation}
    {profileSocialList}

    {data.profileSummaryTitle}

    {profileSummaryDescription}

    {data.profileInterestTitle}

      {profileInterestList}

    {data.profileEducationTitle}

    {profileEducationList}
    ) }

    进行渲染, 我们可以将一些逻辑写在render函数中, 就写法而言react这种用起来是比vue的模板v-for这种更适合有经验的开发者.

    这里有一个知识点需要掌握就是当react的jsx需要循环渲染的时候需要在最外面的节点添加key={index}属性.

    完整代码

    import React, {Component} from 'react';
    import CSSModules from 'react-css-modules';
    import styles from './pc_home.css';
    import {GET, URL} from '../javascripts/http';
    
    @CSSModules(styles, {allowMultiple: true})
    export default class PCHome extends Component {
    
        constructor() {
            super();
            this.state = {
                data: {
                    profileImage: '',
                    profileName: '',
                    profileCareer: '',
                    profileLocation: '',
                    profileSocialList: [],
                    profileSummaryTitle: '',
                    profileSummaryDescription: '',
                    profileInterestTitle: '',
                    profileInterestList: [],
                    profileEducationTitle: '',
                    profileEducationList: []
                }
            }
        }
    
        componentWillMount() {
            GET(URL.fetchProfile).then((data) => {
                this.setState({data: data})
            })
        }
    
        render() {
            const {data} = this.state;
            let profileLocation = data.profileLocation.length ? `Location: ${data.profileLocation}` : ''
            let profileSummaryDescription = data.profileSummaryDescription.split('\n').map((description, index) => (
                

    {description}

    )) let profileSocialList = data.profileSocialList.map((socialVo, index) => (
    )) let profileInterestList = data.profileInterestList.map((interestVo, index) => (
  • # {interestVo.interest}
  • )) let profileEducationList = data.profileEducationList.map((educationVo, index) => (
    {educationVo.major} - {educationVo.year}
    {educationVo.school}
    )) return (
    {data.profileName}
    {data.profileCareer}
    {profileLocation}
    {profileSocialList}

    {data.profileSummaryTitle}

    {profileSummaryDescription}

    {data.profileInterestTitle}

      {profileInterestList}

    {data.profileEducationTitle}

    {profileEducationList}
    ) } }

    学会一个接口请求, 对于其他的就是复制黏贴的重复劳动了, 这样这个简历项目的完整性又有了进一步的提升, 接下来的发展方向是制作一个后台服务, 敬请期待.

    About:

    点击下方链接跳转!!

    :star2: 项目源码 请点这里:star2: >>> 喜欢的朋友请点喜欢 >>> 下载源码的同学请送下小星星 >>> 有闲钱的壕们可以进行打赏 >>> 小弟会尽快推出更好的文章和大家分享 >>> 你的激励就是我的动力!!

    简书稿源:简书 (源链) | 关于 | 阅读提示

    本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
    酷辣虫 » 前端开发 » Web 使用fetch请求后端服务

    喜欢 (0)or分享给?

    专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

    使用声明 | 英豪名录