首页 > 解决方案 > 如何将图像上传到 KeystoneJS GraphQL 端点?

问题描述

我在 KeystoneJS AdminUI 的自定义字段中使用 TinyMCE,这是一个 React 应用程序。我想将 React 前端的图像上传到 KeystoneJS GraphQL 后端。我可以使用添加到 Keystone 服务器的 REST 端点上传图像——向 TinyMCE 传递一个images_upload_handler回调——但我想利用 Keystone 已经为我创建的图像列表/类型构建的 GraphQL 端点。

在此处输入图像描述

我首先尝试使用本文中详细介绍的方法,axios用于上传图像

const getGQL = (theFile) => {
    const query = gql`
  mutation upload($file: Upload!) {
    createImage(file: $file) {
      id
      file {
        path
        filename
      }
    }
  }
`;
// The operation contains the mutation itself as "query"
    // and the variables that are associated with the arguments
    // The file variable is null because we can only pass text
    // in operation variables
    const operation = {
        query,
        variables: {
            file: null
        }
    };
    // This map is used to associate the file saved in the body
    // of the request under "0" with the operation variable "variables.file"
    const map = {
        '0': ['variables.file']
    };

    // This is the body of the request
    // the FormData constructor builds a multipart/form-data request body
    // Here we add the operation, map, and file to upload
    const body = new FormData();
    body.append('operations', JSON.stringify(operation));
    body.append('map', JSON.stringify(map));
    body.append('0', theFile);

    // Create the options of our POST request
    const opts = {
        method: 'post',
        url: 'http://localhost:4545/admin/api',
        body
    };
// @ts-ignore
    return axios(opts);

};

但我不确定要传递什么——我需要从中调用图像上传的theFileTinyMCE接受一个对象,该对象包含给我的函数images_upload_handlerblobInfo

在此处输入图像描述

文件名不起作用,blob 也不起作用——两者都给我服务器错误 500——错误消息不是更具体。

我更喜欢使用 GraphQL 客户端来上传图像——另一篇 SO 文章建议使用apollo-upload-client。但是,我在 KeystoneJS 环境中运行,Apollo-upload-client 说

Apollo 客户端只能有 1 个发送 GraphQL 请求的“终止”Apollo Link;如果已经设置了诸如 apollo-link-http 之类的,请将其删除。

我相信 Keystone 已经设置好了Apollo-link-http(它在搜索中多次出现),所以我认为我不能使用Apollo-upload-client.

标签: node.jsgraphqlapollo-clientapollo-serverkeystonejs

解决方案


我曾经遇到过同样的问题,并通过 Apollo 上传链接解决了它。现在,当应用程序进入生产阶段时,我意识到 Apollo 客户端占用了 1/3 的 gzip 构建文件,我创建了最小的 graphql 客户端,仅用于自动上传图像的 keystone。该软件包在 npm 中可用:https ://www.npmjs.com/package/@sylchi/keystone-graphql-client

如果有用户将头像字段设置为文件,则将 github 徽标上传到用户配置文件的使用示例:

import {  mutate } from  '@sylchi/keystone-graphql-client'

const  getFile  = () =>  fetch('https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png',
{
    mode:  "cors",
    cache:  "no-cache"
})
.then(response  =>  response.blob())
.then(blob  => {
    return  new  File([blob], "file.png", { type:  "image/png" })
});

getFile().then(file  => {

const  options  = {
    mutation: `
        mutation($id: ID!, $data: UserUpdateInput!){
            updateUser(id: $id, data: $data){
                id
            }
        }
    `,
    variables: {
        id:  "5f5a7f712a64d9db72b30602", //replace with user id
        data: {
            avatar:  file
        }
    }
}

mutate(options).then(result  =>  console.log(result));

});

整个包只有 50loc 和 1 个依赖 :)


推荐阅读