无法使用 apollo-server-micro 和 NextJS 上传 1MB 以上的文件
Posted
技术标签:
【中文标题】无法使用 apollo-server-micro 和 NextJS 上传 1MB 以上的文件【英文标题】:Not able to upload files above 1MB using apollo-server-micro & NextJS 【发布时间】:2021-05-27 05:01:17 【问题描述】:希望您能帮助我解决以下问题。我正在尝试通过首先将文件转换为 DataURL,然后将其作为字符串发送,将 ≈3MB 的 excel 文件从客户端上传到 API。这适用于较小的文件,但它似乎以某种方式阻止了我的较大文件。
当我上传文件时,我收到以下错误。
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>
)
【问题讨论】:
【参考方案1】:export const config =
api:
bodyParser: false
将 bodyParser 设置为 true
【讨论】:
【参考方案2】:您尝试在 json 中将文件作为字符串发送?我认为您应该在客户端使用多部分/表单数据,并在服务器端使用特殊的中间件解析它们 在客户端特殊链接将请求转换为 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(
s-s-rMode: 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 s-s-r 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
【讨论】:
以上是关于无法使用 apollo-server-micro 和 NextJS 上传 1MB 以上的文件的主要内容,如果未能解决你的问题,请参考以下文章
更新到 nextjs 11 后的 Micro MODULE_NOT_FOUND
无法使用 StorageClass 配置卷 - 无法获取存储帐户的存储密钥