javascript 无法使用apollo-server-micro & NextJS上传1 MB以上的文件

rmbxnbpk  于 2023-02-18  发布在  Java
关注(0)|答案(3)|浏览(112)

希望你能帮我解决以下问题。我试图从客户端上传一个约3MB的excel文件到API,首先将文件转换为DataURL,然后将其作为字符串发送。这适用于较小的文件,但不知何故,它似乎阻止了我的较大文件。
当我上传文件时,我收到以下错误。

POST body missing. Did you forget use body-parser middleware?

我已经做了自己的研究,发现更多的人有同样的问题,虽然我找不到解决方案。https://github.com/apollographql/apollo-server/issues/792
这是我在服务器端使用的代码。

import { ApolloServer, gql } from 'apollo-server-micro'

type Props = {
    _id: string
    file: string[]
}

const typeDefs = gql`
    type Mutation {
        uploadFile(file: [String!]!): Boolean!
    }
    type Query {
        readUpload(_id: String!): Boolean!
    }
`

const resolvers = {
    Mutation: {
        async uploadFile(_: any, { file }: Props) {   
            console.log(file)
            
            return true
        }
    },
    Query: {
        async readUpload(_: any, { _id }: Props) {
        }
    }
}

const apolloServer = new ApolloServer({ 
    typeDefs, 
    resolvers
})

export const config = {
    api: {
        bodyParser: false
    }
}

// Ensure to put a slash as the first character to prevent errors.
export default apolloServer.createHandler({ path: '/api/uploads' })

这是我在客户端使用的代码。

import { useRef } from 'react'

import { uploadFile } from '../graphql/fetchers/uploads'
import { UPLOAD_FILE_QUERY } from '../graphql/queries/uploads'

export default function Upload() {
    const inputElement = useRef<HTMLInputElement>(null)

    const submitForm = (event: any) => {
        event.preventDefault()
        const files = inputElement.current?.files

        if (files) {
            const fileReader = new FileReader()

            fileReader.onload = async () => {
                try {
                    const result = fileReader.result as string
                    try {
                        console.log(result)
                        await uploadFile(UPLOAD_FILE_QUERY, { file: result })  
                    } catch(error) {
                        console.log(error)
                    }           
                } catch(error) {
                    console.log(error)
                }
            }
            fileReader.readAsDataURL(files[0]) 
        }
    }

    return (
        <form>
            <input ref={inputElement} type='file'></input>
            <button onClick={(event) => submitForm(event)}>Submit</button>
        </form>
    )
}
qxgroojn

qxgroojn1#

export const config = {
    api: {
        bodyParser: false
    }
}

将bodyParser设置为true

q3qa4bjr

q3qa4bjr2#

设置bodyParser大小限制

export const config = {
   api: {
     bodyParser: {
        sizeLimit: '4mb' // Set desired value here
     }
   }
}
lxkprmvk

lxkprmvk3#

你尝试在json中以字符串形式发送文件吗?我认为你应该在客户端使用multipart/form数据,并在服务器端使用特殊的中间件解析它们。在客户端特殊链接将请求转换为multipart/formdata完整示例https://github.com/jaydenseric/apollo-upload-examples

import { useMemo } from "react"
import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client"
import { setContext } from "@apollo/client/link/context"
import { getUserTokenFromLocalStorage } from "../utils/utils"
import { createUploadLink } from "apollo-upload-client"
let apolloClient

const httpLink = createUploadLink({
  uri: "/api/graphql",
  headers: {
    "keep-alive": "true",
  },
})

const authLink = setContext((_, { headers }) => {
  let token = getUserTokenFromLocalStorage()
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    },
  }
})

function createIsomorphLink() {
  if (typeof window === "undefined") {
    const { SchemaLink } = require("@apollo/client/link/schema")
    const { schema } = require("./schema")
    return new SchemaLink({ schema })
  } else {
    return authLink.concat(httpLink)
  }
}

function createApolloClient() {
  return new ApolloClient({
    ssrMode: typeof window === "undefined",
    link: createIsomorphLink(),
    cache: new InMemoryCache(),
  })
}

export function initializeApollo(initialState = null) {
  const _apolloClient = apolloClient ?? createApolloClient()

  // If your page has Next.js data fetching methods that use Apollo Client, the initial state
  // gets hydrated here
  if (initialState) {
    _apolloClient.cache.restore(initialState)
  }
  // For SSG and SSR always create a new Apollo Client
  if (typeof window === "undefined") return _apolloClient
  // Create the Apollo Client once in the client
  if (!apolloClient) apolloClient = _apolloClient

  return _apolloClient
}

export function useApollo(initialState) {
  const store = useMemo(() => initializeApollo(initialState), [initialState])
  return store
}

相关问题