JS 封装fetch 上传文件+返回json+返回文件流

⏹前端html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>封装fetch</title>
</head>
<body>
    <button id="btn1">
        发送Ajax请求,获取json数据
    </button>
    <hr>
    <button id="btn2">
        发送Ajax请求,获取Blob对象
    </button>
    <hr>
    <button id="btn3">
        发送Ajax请求,上传文件和表单数据到后端
    </button>
    <form id="form">
        <input type="file" id="file1">
        <input type="file" id="file2">
        <input type="text" name="name" id="name">
    </form>
    
</body>
<script src="https://cdn.staticfile.org/jquery/1.10.0/jquery.js"></script>
<script type="module" src="./js/07-main.js"></script>
</html>

⏹主函数

import fetchAjax from './07-fetchAjax.js'

document.querySelector('#btn1').addEventListener('click', async () => {

    const requestConfig = {
        method: 'GET', 
    }

    // 🤠发送POST请求,获取json数据
    const result = await fetchAjax('https://api.github.com/users/fengyehong123', null, requestConfig);
    console.log(result);
});

btn2.addEventListener('click', async () => {

    const requestConfig = {
        method: 'GET', 
        returnBlobFlag: true
    }

    // 🤠发送get请求,获取Blob对象
    const file = await fetchAjax('http://localhost:8082/wjec/file/manyFileDownLoad/2.txt', null, requestConfig);
    console.log(file);
})

btn3.addEventListener('click', async () => {

    // 构造FormData表单对象
    const formData = new FormData(document.querySelector('#form'));
    formData.append('file', document.querySelector('#file1').files[0]);
    formData.append('file', document.querySelector('#file2').files[0]);
	
	// 🤠同时提交文件和表单数据到后台,获取响应
    const result = await fetchAjax('http://localhost:8082/wjec/file/receiveData', formData);
    console.log(result);
});

⏹封装的fetch

// 默认配置项
const fetchOptions = {
    headers: {
        'Content-Type': 'application/json;charset=utf-8',
    },
    method: 'POST',
    // 默认设置请求超时时间,且超时时间为6秒钟
    timeoutFlag: true,
    timeout: 6000,
    // 默认不返回blob对象,返回json
    returnBlobFlag: false,
    // 默认值,同源请求时发送Cookie,跨域请求时不发送.
    credentials: "same-origin",
    // 没有权限时,需要跳转到的画面
    loginPath: '/login.html',
}

// 设置请求对象的配置信息
const setRequestConfig = (param, options = {}) => {

    // 配置对象合并
    const defaultOptions = {
        ...fetchOptions,
        ...options
    };

    // 判断传入的参数是否为FormData实例
    const formDataKbn = param instanceof FormData;

    // 如果不是GET请求,就添加body配置项
    if (defaultOptions.method !== 'GET') {
        // 如果是FormData表单对象,就直接放入,否则解析为json字符串
        defaultOptions.body = formDataKbn ? param : JSON.stringify(param);
    }

    // 如果是文件上传的话,就删除headers请求头属性
    if(formDataKbn) Reflect.deleteProperty(defaultOptions, "headers");

    // 请求头
    const headers = new Headers(defaultOptions.headers);

    // 请求对象
    const requestConfig = {
        // 将默认的配置对象解构到请求对象中
        ...defaultOptions,
        headers,
    }
    return requestConfig;
}

// fetch的Ajax请求
const fetchAjax = async (url, param, options = {}) =>  {

    // 设置请求对象的配置信息
    const requestConfig = setRequestConfig(param, options);
    const request = new Request(url, requestConfig);

    // 超时函数
    let abortId;
    let timeout = false;
    if (requestConfig.timeoutFlag) {
        abortId = setTimeout(() => {
            timeout = true;
        }, requestConfig.timeout);
    }

    try {
        // 发送请求,获取响应
        const response = await fetch(request);
        // 判断请求是否超时
        if (timeout) {
            /*
                任何一个await语句后面的Promise对象变为reject状态,那么整个async函数都会中断执行
                因此Promise.reject()前面必须添加await
            */ 
            await Promise.reject('timeout');
        }

        const {
            status, 
            statusText
        } = response;

        // 没有权限则跳转登录画面
        if ([401, 403].includes(status)) {
            window.location = requestConfig.loginPath;
        }
        // 如果请求失败
        if(status < 200 || status >= 300) {
            return new Error(statusText);
        }
        
        // 文件流对象flag
        if (requestConfig.returnBlobFlag) {
            return response.blob();
        } else {
            return response.json();
        }
    } catch (error) {
        console.log(error);
    } finally {
        // 请求超时延时器
        clearTimeout(abortId);
    }
}

export default fetchAjax;

⏹效果
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值