簡體   English   中英

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

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

希望您能幫助我解決以下問題。 我正在嘗試將 ≈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> ) }

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

將 bodyParser 設置為 true

您嘗試在 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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM