node.js - 如何将图像上传到 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);
};
但我不确定要传递什么——我需要从中调用图像上传的theFile
TinyMCE接受一个对象,该对象包含给我的函数images_upload_handler
blobInfo
文件名不起作用,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
.
解决方案
我曾经遇到过同样的问题,并通过 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 个依赖 :)
推荐阅读
- node.js - 在 Google App Engine 中运行时,Nodejs 应用程序无法连接到 Firebase 实时数据库
- c++ - error : Function definition is not allowed here
- python - 如何使用 python 求解 csv 文件上的两个不同的依赖方程?
- database - Neo4j - 准备 CSV 数据
- linux - 在 ubuntu 上安装 libgconf-2-4
- matrix - 如何在 IlNumerics 数组中查找行
- python - 只有三个最好的堆积条形图
- r - 在 R 中重塑数据框。仅将某些必需的列转换为行
- prolog - 规则的意外结果
- react-native - React_Native Modal 在两个屏幕之间导航时正在关闭