You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中通过RTK Query获取PDF文件失败求助

解决RTK Query获取PDF时的JSON解析错误

问题原因

RTK Query 默认会尝试将响应解析为 JSON,即便你设置了 responseType: 'blob',若配置不当,它仍会触发JSON解析逻辑,导致PDF二进制数据被当作JSON解析,抛出Unexpected token: %错误(PDF文件开头通常是%PDF-)。

修复方案

1. 正确配置Query的responseType与transformResponse

在你的CourseApi中,需确保两点:

  • 在query配置里设置responseType: 'blob',明确告知RTK Query以Blob格式接收响应
  • 移除transformResponse里的response.blob()调用——当responseType设为blob时,响应本身已经是Blob对象,无需再次转换;若需自定义处理,直接返回该Blob即可

示例代码:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const courseApi = createApi({
  reducerPath: 'courseApi',
  baseQuery: fetchBaseQuery({ baseUrl: '你的API基础地址' }),
  endpoints: (builder) => ({
    getTranscript: builder.query<Blob, string>({
      query: (courseId) => ({
        url: `/courses/${courseId}/transcript`,
        responseType: 'blob', // 关键配置:指定响应类型为blob
      }),
      // 直接返回Blob,无需额外转换
      transformResponse: (response: Blob) => response,
    }),
  }),
});

export const { useGetTranscriptQuery } = courseApi;

2. 确认API响应的Content-Type

确保后端返回的响应头Content-Type确实为application/pdf,RTK Query会结合这个响应头与responseType配置正确处理响应,避免解析错误。

3. 调用Query后的PDF处理示例

在组件中获取到Blob对象后,可通过React Native生态库(如expo-file-system或react-native-fs)实现下载/预览逻辑:

import { useGetTranscriptQuery } from './courseApi';
import * as FileSystem from 'expo-file-system';
import { Button } from 'react-native';

const TranscriptDownloadButton = ({ courseId }) => {
  const { data: transcriptBlob, isLoading } = useGetTranscriptQuery(courseId);

  const handleDownload = async () => {
    if (!transcriptBlob) return;
    
    // 将Blob转为Base64后写入本地文件
    const base64Data = await new Promise((resolve) => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result?.split(',')[1]);
      reader.readAsDataURL(transcriptBlob);
    });
    
    const fileUri = `${FileSystem.documentDirectory}transcript.pdf`;
    await FileSystem.writeAsStringAsync(fileUri, base64Data, {
      encoding: FileSystem.EncodingType.Base64
    });
    // 可在此处添加打开文件的逻辑
  };

  return (
    <Button
      title={isLoading ? '加载中...' : '下载成绩单'}
      onPress={handleDownload}
      disabled={isLoading || !transcriptBlob}
    />
  );
};

关键注意点

  • 不要在transformResponse中调用response.blob():当responseType设为blob时,response已经是Blob实例,response.blob()会返回Promise,RTK Query同步处理时会将这个Promise当作普通值,引发后续解析错误。
  • 若需异步处理响应,transformResponse可返回Promise,但要确保后续逻辑能正确处理异步结果;对于Blob获取场景,通常无需额外异步操作。

内容的提问来源于stack exchange,提问作者Rabia Shahzad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:17:33