node.js - 使用 Graphql 上传文件时遇到问题
问题描述
我正在使用 graphql 并尝试将文件从 react 上传到 localhost 服务器。
我正在从阿波罗服务器官方文档中学习本教程:在阿波罗服务器中启用文件上传
由于某种原因,图像已损坏(它是空的),我不知道如何修复它。我已经尝试过很多没有运气的事情。
在这一点上,我迫切需要任何解决方法或解决方案。
类型定义
const {gql} = require('apollo-server')
module.exports = gql`
type File {
url: String!
filename: String!
mimetype: String!
encoding: String!
}
type Mutation {
uploadFile(file: Upload!): File!
}
`
解析器
const fs = require("fs");
const path = require("path");
module.exports = {
Query: {
test: () => 'Test completed',
files: () => files
},
Mutation: {
uploadFile: async (parent, {file}) => {
const {createReadStream, filename, mimetype, encoding} = await file
const stream = await createReadStream()
const pathName = path.join(__dirname, `../../public/images/${filename}`)
await stream.pipe(fs.createWriteStream(pathName))
return {
filename,
mimetype,
encoding,
url: `http://locahost:5000/images/${filename}`}
},
}
}
阿波罗客户端设置
import React from 'react'
import App from './App'
import ApolloClient from 'apollo-client'
import {InMemoryCache} from 'apollo-cache-inmemory'
import {createUploadLink} from 'apollo-upload-client'
import {ApolloProvider} from '@apollo/react-hooks'
import {setContext} from 'apollo-link-context'
const httpLink = createUploadLink({
uri: 'http://localhost:5000/graphql/'
})
const authLink = setContext(() => {
const token = localStorage.getItem('jwtToken')
return {
headers: {
authorization: token ? `Bearer ${token}` : ''
}
}
})
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
})
export default (
<ApolloProvider client={client}>
<App/>
</ApolloProvider>
)
反应代码本身
import React from 'react'
import {useMutation, gql} from '@apollo/client'
const UPLOAD_FILE = gql`
mutation uploadFile($file: Upload!) {
uploadFile(file: $file) {
url
mimetype
filename
encoding
}
}
`
function UploadForm() {
const [uploadFile] = useMutation(UPLOAD_FILE, {
onCompleted: data => console.log(data)
})
const handleFileChange = e => {
const file = e.target.files[0]
if(!file) return
uploadFile({variables: {file}})
}
return (
<div>
<h2>Upload file</h2>
<input type='file' onChange={handleFileChange}/>
</div>
)
}
export default UploadForm
控制台输出
uploadFile: {…}
__typename: "File"
encoding: "7bit"
filename: "91f29c99.jpg"
mimetype: "image/jpeg"
url: "http://locahost:5000/images/91f29c99.jpg"
UPD:我已经尝试过这种方法。现在有时我会得到非空图像,但它们仍然损坏且无法读取。但大多数时候它仍然是空的。
uploadFile: async (_, {file}) => {
const {createReadStream, filename} = await file;
await new Promise((resolve, reject) =>
createReadStream()
.pipe(fs.createWriteStream(path.join(__dirname, `../../public/images/${filename}`))
.on("finish", () => resolve())
.on("error", reject))
)
return {
url
}
},
解决方案
推荐阅读
- php - 获取mysql更新成功的确认
- php - Docker 安装 cURL 失败(需要 7.10.5 或更高版本)
- sql - 如何将 PostgreSQL 的`::FLOAT` 翻译成 MariaDB
- google-apps-script - 在复制到新工作表之前如何检查单元格是否为空?
- python - 在图像上查找图像
- sql - ORACLE SQL Group By STILL 给 Duplicates
- python - LDA 检测新出现的主题
- java - stack.pop() 返回什么?
- selenium - 如何拖放以偏移硒测试中的元素,以便它可以在 FireFox 上运行
- c# - OWIN + Ninject w/ UseNinjectMiddleware 不处理