nuxt3 使用$fetch封装(typescript)客户端使用的http请求方法

本文讲述了在Nuxt3中使用fetchAPI进行HTTP请求时,如何配合服务器端渲染(SSR)处理后端返回的数据,包括内容类型判断、预处理及错误处理。作者强调了fetch在onResponse阶段的数据解析和自定义处理的重要性。
摘要由CSDN通过智能技术生成

nuxt3提供了usefetch()之类的方法来发起请求,他提供的这些方法貌似都是考虑和server端配合使用的,比如说在页面初始化前,有些数据是由后端提供,但是为了按SSR来渲染页面,就可以使用usefetch()来配合server先从后端获取数据,再渲染页面。所以我看文档,都是使用await等待,和之前我接触的异步请求非常不同。

而我想要的做的是由客户端直接向后端发起http请求的方法,usefetch()好像也可以设置只由客户端发起请求来使用,但是却没法由我自己来预处理后端返回的数据。

场景

后端返回的数据,有可能是json,也有可能是blob。这得由请求头"content-type"来确定。所以,需要对响应做预处理。研究了一圈,以前使用的axios貌似被nuxt3抛弃了,nuxt3支持的是fetch,那就用它自带的工具,也就不用再引入第三方库了。

let baseUrl = "http://127.0.0.1/";
// 指定后端返回的基本数据类型
export interface IResponse<T> {
    data?: T;
    code: number;
    headers: Headers;
}
function fetch<T>(url: string, options?: any): Promise<IResponse<T>> {
    return $fetch<IResponse<T>>(url, {
        ...options,
        baseURL: baseUrl,
        onResponse({ response }) {
            // fetch 是会自动解析数据的,进入onResponse前就已经解析过了,它会智能地解析 JSON 和本机值,如果解析失败,则返回到文本,解析的结果就是response._data
            let contentType = response.headers.get("content-type");
            // 请求码不为200等正常码的情况
            if (!response.ok) {
                // 这里的_data,会被后面catch捕获,因为你可能还需要获取headers等数据,所以需要在这里处理一下数据
                response._data = { code: -1, data: "请求已到达服务器但未正常响应:" + response.statusText, headers: response.headers };
                return;
            }
            // 我的后端只由json和blob两种类型,如果你的不止,那么就自己根据实际情况修改
            if (!contentType) {
                // 如果没有content-type,则认为返回的数据不符合预期
                response._data = { code: -1, data: "返回数据不符合预期" };
                return;
            } else if (contentType == "application/json; charset=utf-8") {
                //给数据再添加headers
                response._data.headers = response.headers; 
                return;
            } else {
                // 后端返回的文件流,会包含该请求头
                const disposition = response.headers.get("content-disposition");
                if (!disposition) {
                    response._data = { code: -1, data: "返回数据不符合预期" };
                    return;
                }
                // 切割出文件名,后端返回格式不同处理就不同
                const blob = new Blob([response._data], { type: contentType });
                // 创建ObjectURL,返回给前端
                const blobUrl = window.URL.createObjectURL(blob);
                response._data = { code: 1, data: blobUrl, headers: response.headers };
                return;
            }
        },
        onRequestError({ error }) {
            // 请求失败的回调,这里的失败是指那种网络不通的之类请求都没到后端的情况,而不是后端返回码不是200之类的情况
            // 后端返回错误码的情况归onResponse管,这里只处理请求不通的情况
        },
    }).catch((error) => {
        // 请求不为200等正常码的情况,这里会捕获到,并返回给前端
        return error.data;
    });
}
// 此处的url,无需包含baseUrl
export function get<T>(url: string, params?: any) {
    return fetch<T>(url, { method: "get", ...params });
}

export function post<T>(url: string, params?: any) {
    return fetch<T>(url, { method: "post", ...params });
}

关键点:fetch在onResponse()前就已经只能解析数据了,只需要通过response._data获取解析的结果就好,并且这个结果由你修改,然后前端接收的就是你修改后的结果

nuxt3 的 $fetch基于ofetch,所以,其余配置直接看它就可以,或者看nuxt3的usefetch(),它有什么参数,$fetch应该也有。

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值