简体   繁体   English

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

[英]Not able to upload files above 1MB using apollo-server-micro & NextJS

Hope you could help me out with the following.希望您能帮助我解决以下问题。 I am trying to upload an excel file of ≈3MB from the client side to the API by first converting the file to a DataURL where after I send it as a string.我正在尝试将 ≈3MB 的 excel 文件从客户端上传到 API,方法是首先将文件转换为 DataURL,然后将其作为字符串发送。 This is working for smaller files, but it somehow seems to be blocking my larger files.这适用于较小的文件,但它似乎以某种方式阻止了我的较大文件。

When I upload the file, I get the following error.当我上传文件时,我收到以下错误。

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

I have done my own research and found more people with the same problem, though I could not find a solution.我做了自己的研究,发现更多人有同样的问题,但我找不到解决方案。 https://github.com/apollographql/apollo-server/issues/792 https://github.com/apollographql/apollo-server/issues/792

This is the code I am using on the server side.这是我在服务器端使用的代码。

 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' })

This is the code I am using on the client side.这是我在客户端使用的代码。

 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> ) }

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

set bodyParser to true将 bodyParser 设置为 true

you try to send file as string in json?您尝试在 json 中将文件作为字符串发送? I think you should use multipart/form data on client side and parse them with special middleware on server side On client special link converts request to multipart/formdata full example https://github.com/jaydenseric/apollo-upload-examples我认为您应该在客户端使用 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM