无法使用 GraphQL 和 Apollo 将文件上传到 Strapi

Posted

技术标签:

【中文标题】无法使用 GraphQL 和 Apollo 将文件上传到 Strapi【英文标题】:Can't upload a file to Strapi using GraphQL and Apollo 【发布时间】:2021-05-18 21:56:14 【问题描述】:

我有一个 React/Next.js 应用程序,它使用 GraphQL 和 Apollo 来连接无头 API 并与之交互。我使用 Strapi 作为我的无头 API/CMS,它工作得很好,除了一个问题。我正在尝试使用 GraphQL 突变将我的 React 应用程序中的文件上传到我的 Strapi CMS 中的内容类型,但它在上传部分一直失败。

当我使用 Altair(我的游乐场环境)将具有完全相同突变的文件上传到 Strapi 时,一切正常,但是一旦我尝试从我的 React 应用程序运行相同的突变,我就会收到此错误: Variable \"$file\" got invalid value ; Upload value invalid.。我在网上看到的所有内容都使用apollo-upload-client 提出,并将link: createUploadLink( uri: "http://localhost:4300/graphql" ), 之类的内容添加到我的Apollo 客户端启动中。我已经尝试过了,但每当我使用它时,它都会破坏我的应用程序,并且我收到此 GraphQL 错误Error: Cannot return null for non-nullable field UsersPermissionsMe.username.

似乎我能找到的唯一答案是使用apollo-upload-client,但是当我使用它时,它似乎破坏了我的应用程序。我不知道我是否需要以不同的方式使用它,可能是因为我使用的是 Strapi、Next 或 @apollo/client。我对这个有点迷茫。

这就是我启动我的 Apollo 客户端的方式,当一切正常时,除了上传文件。

import  ApolloClient, InMemoryCache, NormalizedCacheObject  from "@apollo/client";
import  parseCookies  from "nookies";
import  useMemo  from 'react'
import getConfig from "next/config";
const  publicRuntimeConfig  = getConfig();

let apolloClient: ApolloClient<NormalizedCacheObject>;

function createApolloClient(ctx) 
    return new ApolloClient(
        s-s-rMode: typeof window === "undefined",
        uri: publicRuntimeConfig.PUBLIC_GRAPHQL_API_URL,
        cache: new InMemoryCache(),
        headers: 
            Authorization: `Bearer $ctx ? parseCookies(ctx).jwt : parseCookies().jwt`,
        ,
    );

我的应用程序在此代码下运行完美,除了每当我尝试上传文件时都会收到"message":"Variable \"$file\" got invalid value ; Upload value invalid.",。所以当我尝试使用apollo-upload-client 来解决这个问题时:

import  ApolloClient, InMemoryCache, NormalizedCacheObject  from "@apollo/client";
import  createUploadLink  from 'apollo-upload-client';
import  parseCookies  from "nookies";
import  useMemo  from 'react'
import getConfig from "next/config";
const  publicRuntimeConfig  = getConfig();

let apolloClient: ApolloClient<NormalizedCacheObject>;

function createApolloClient(ctx) 
    return new ApolloClient(
        s-s-rMode: typeof window === "undefined",
        // uri: publicRuntimeConfig.PUBLIC_GRAPHQL_API_URL,
        link: createUploadLink( uri: publicRuntimeConfig.PUBLIC_GRAPHQL_API_URL ),
        cache: new InMemoryCache(),
        headers: 
            Authorization: `Bearer $ctx ? parseCookies(ctx).jwt : parseCookies().jwt`,
        ,
    );


我收到此错误:Error: Cannot return null for non-nullable field UsersPermissionsMe.username.

我还是 GraphQL 和 Strapi 的新手,所以我可能遗漏了一些明显的东西。一切正常,除了上传。我可以从我的 Playground 上传,而不是从我的应用程序上传,这就是我所在的地方。

【问题讨论】:

【参考方案1】:

所以在这个问题两天后,我在阅读 apollo-upload-client 文档 10 分钟后弄明白了。太丢脸了。我需要做的就是将我的标头请求从 ApolloClient 选项移动到 createUploadLink 选项。最终修复是

function createApolloClient(ctx) 
    return new ApolloClient(
        s-s-rMode: typeof window === "undefined",
        link: createUploadLink(
            uri: publicRuntimeConfig.PUBLIC_GRAPHQL_API_URL,
            headers: 
                Authorization: `Bearer $ctx ? parseCookies(ctx).jwt : parseCookies().jwt`,
            ,
        ),
        cache: new InMemoryCache(),
    );

【讨论】:

以上是关于无法使用 GraphQL 和 Apollo 将文件上传到 Strapi的主要内容,如果未能解决你的问题,请参考以下文章

无法将 GraphQL 查询从 Apollo 客户端发送到 Rails GraphQL 后端

Apollo Android (GraphQL) 自定义类型构建文件警告:“无法为最终字段赋值”

无法在 Next.js 应用程序中使用 Apollo-client GraphQL 上传文件:缺少 POST 正文

GraphQL:无法读取 Apollo 客户端中的响应标头

在 GraphQL 和 Apollo 中检索数组

使用 Apollo 和 GraphQL 缓存而不是 Vuex?