使用 Graphql 上传文件时遇到问题

时间:2021-03-15 13:57:04

标签: node.js reactjs graphql

我正在使用 graphql 并尝试从 react 将文件上传到本地主机服务器。

我是从 apollo 服务器官方文档中学习本教程的:Enabling file uploads in Apollo Server

由于某种原因,图像已损坏(为空),我不知道如何修复它。我已经尝试了很多东西,但都没有运气。

此时,我迫切需要任何变通方法或解决方案。

类型定义

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}`} 
        },
    }   
}

Apollo 客户端设置

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
            } 

        },

0 个答案:

没有答案
相关问题