zhangsanshi / issue-blog

It's a blog rather than issue
0 stars 0 forks source link

fetch easy #36

Open zhangsanshi opened 7 years ago

zhangsanshi commented 7 years ago

util.js

const toString = Object.prototype.toString;

export function isString(str) {
    if (str == null) {
        return false;
    }
    return toString.call(str) === '[object String]';
}

export function isObject(obj) {
    if (obj == null) {
        return false;
    }
    return toString.call(obj) === '[object Object]';
}
import qs from 'qs';
import { isString, isObject } from './util.js';

const hasOwnProperty = Object.prototype.hasOwnProperty;

// 检查是否需要格式化
function isFormatBody(body) {
    const isFormData = body instanceof FormData;
    const isBlob = body instanceof Blob;
    const isURLSearchParams = body instanceof URLSearchParams;
    return isFormData || isBlob || isURLSearchParams || isString(body);
}
// 检查 request 的 content type
function isDefault(contentType = '') {
    return contentType.indexOf('application/x-www-form-urlencoded') !== -1;
}
function isFormData(contentType = '') {
    return contentType.indexOf('multipart/form-data') !== -1;
}
// 生成 form data
function getFormData(obj) {
    const fd = new FormData();
    for (let key in obj) {
        if (hasOwnProperty.call(obj, key)) {
            fd.append(key, obj[key]);
        }
    }
    return fd;
}
// 检查返回的状态
function checkStatus(response) {
    if (response.status >= 200 && response.status < 300) {
        return response;
    } else {
        const error = new Error(response.statusText);
        error.response = response;
        throw error;
    }
}
// 默认把返回值 json 化
function parseJSON(response) {
    const respContentType = response.headers.get('Content-Type');
    if (respContentType.indexOf('/json') !== -1) {
        return response.json();
    }
    const error = new Error('返回值出错');
    error.response = response;
    throw error;
}
function FetchEasy(url, data= {}, ops = {}) {
    const defaultOps = {
        mode: 'same-origin',
        credentials: 'same-origin',
    };
    const init = Object.assign({}, defaultOps, ops);
    // 替换 url 中的变量
    if (url.indexOf(':') !== -1) {
        url = url.replace(/:(.*?)(?=\/|\.|$)/g, (a, b) => {
            return encodeURIComponent(data[b] || '');
        });
    }
    const method = init.method = init.method || 'get';
    const body = init.body;
    // 设置 request header
    let headers = init.headers = Object.assign({
        'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }, init.headers);
    // 设置 request body
    if (method !== 'get' && method !== 'head') {
        if (body && isObject(body) && !isFormatBody(body)) {
            const contentType = headers['Content-type'];
            if (isDefault(contentType)) {
                init.body = qs.stringify(body);
            } else if (isFormData(contentType)) {
                init.body = getFormData(body);
            } else {
                init.body = JSON.stringify(body);
            }
        }
    } else if (body) {
        delete init.body;
        const query = qs.stringify(body);
        url += url.indexOf('?') === -1 ? '?' + query : '&' + query;
    }

    return fetch(url, init).then(checkStatus).then(parseJSON);
}
export default FetchEasy;
zhangsanshi commented 7 years ago

使用的时候

 FetchEasy('/api/:id', {
    id: 2
}, {
  method: 'get'
})
zhangsanshi commented 7 years ago

目前的实现有点怪,新的实现正在coding