Vue Apollo 上传文件崩溃节点最大调用堆栈大小超过 _openReadFs

Posted

技术标签:

【中文标题】Vue Apollo 上传文件崩溃节点最大调用堆栈大小超过 _openReadFs【英文标题】:Vue Apollo Upload file crashes Node Maximum call stack size exceeded at _openReadFs 【发布时间】:2021-12-28 02:17:55 【问题描述】:

我正在尝试使用 Apollo-boost-upload 为 graphQl 文件上传设置前端。后端代码基于此链接 https://dev.to/dnature/handling-file-uploads-with-apollo-server-2-0-14n7。 在 server.js 文件中添加以下行后,它现在到达解析器断点

const  apolloUploadExpress  = require("apollo-upload-server");

app.use(apolloUploadExpress( maxFileSize: 1000000000, maxFiles: 10 ));

修改上传类型的架构后

scalar Upload

这里是 Vue 组件

 <input
    type="file"
    style="display:none"
    ref="fileInput"
    accept="image/*"
    @change="upload"
>

//Upload method 
  upload( target:  files = []  ) 
        if (!files.length) 
          return;
        
        this.logoImage = files[0];
      ,

//Dispatching action from vue component

this.$store.dispatch("uploadLogo",  image: this.logoImage );

//Vuex action
const uploadLogo = async (context, payload) => 
  context.commit("setLoading", true);
  try 
    const  data  = await apolloClient.mutate(
      mutation: UPLOAD_LOGO,
      variables: file: payload.image,
      context: 
        hasUpload: true,
      ,
    );
    context.commit("setLoading", false);
    console.log("Logo:", data.uploadLogo);
   catch (error) 
    context.commit("setLoading", false);
    console.log(error);
  
;

//Mutation
export const UPLOAD_LOGO = gql`
  mutation uploadLogo($file: Upload!) 
    uploadLogo(file: $file) 
      _id
      path
      filename
      mimetype
      user 
        _id
      
    
  
`;


// Apolloclient config on main.js

import ApolloClient from "apollo-boost-upload";

import  InMemoryCache  from "apollo-boost";
import VueApollo from "vue-apollo";


// Set up Apollo Client
export const defaultClient = new ApolloClient(
  uri: "http://localhost:4000/graphql",
  cache: new InMemoryCache(
    addTypename: false,
  ),
 
  fetchOptions: 
    credentials: "include",
  ,
  request: (operation) => 
    // if no token in local storage, add it
    if (!localStorage.someToken) 
      localStorage.setItem("someToken", "");
    
    // operation adds the token to authorizatrion header, which is sent o backend
    operation.setContext(
      headers: 
        authorization: "Bearer " + localStorage.getItem("someToken"),
      ,
    );
  ,
  onError: ( graphQLErrors, networkError ) => 
    if (networkError) 
      console.log("[networkError]", networkError);
    
    if (graphQLErrors) 
      for (const error of graphQLErrors) 
        console.dir(error);
        if (error.name === "AuthenticationError") 
          // set auth errir in state
          store.commit("setError", error);
          // signout user to clear error
          store.dispatch("signUserOut");
        
      
    
  ,
);

这是来自后端的更新的 typedef(旧代码已注释掉),如果这有助于识别问题

const logoUploadTypeDefs = gql`
  type File 
    _id: ID!
    path: String!
    filename: String!
    mimetype: String!
    encoding: String!
    user: User
  

  # input Upload 
  #   name: String!
  #   type: String!
  #   size: Int!
  #   path: String!
  # 

  scalar Upload

  type Mutation 
    uploadLogo(file: Upload!): File
  
  type Query 
    info: String
    logo: File!
  
`;

现在,Node 应用程序崩溃并显示以下日志

【问题讨论】:

github.com/jaydenseric/graphql-multipart-request-spec @xadm 谢谢,我已经取得了一些进展(请参阅更新的问题)。在前端和后端进行一些修改后,它现在到达解析器。上传的文件正在到达后端。现在,我在后端遇到了另一个问题,如屏幕截图所示。 【参考方案1】:

我不得不将“apollo-upload-server”更改为“graphql-upload”

更改 1:

注释掉“apollo-upload-server”并使用“graphql-upload”

// const  apolloUploadExpress  = require("apollo-upload-server");]
const 
  graphqlUploadExpress, // A Koa implementation is also exported.
 = require("graphql-upload");

在中间件中,使用了这个

更改 2:

app.use(graphqlUploadExpress());
await apolloServer.start();

代替旧代码

app.use(apolloUploadExpress());// Not to be used
await apolloServer.start();

另外,在解析器中,我添加了这个

更改 3:

从解析器文件中的graphql-upload导入上传

const  GraphQLUpload  = require("graphql-upload");

....
....

const resolvers = 
  // This maps the `Upload` scalar to the implementation provided
  // by the `graphql-upload` package.
  Upload: GraphQLUpload,
  Query: 
      ....
   
  Mutations: 
      ....
  


请参阅Apollo 文档了解更多详情。这解决了 Node 因错误“_openReadFs 超出最大调用堆栈大小...”而崩溃的问题

【讨论】:

以上是关于Vue Apollo 上传文件崩溃节点最大调用堆栈大小超过 _openReadFs的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Vue 路由器会抛出最大调用堆栈错误?

vue-gtag 错误:“超出最大调用堆栈大小”

Vue v3中的VideoJS播放列表超过最大调用堆栈大小错误

Vue.js“超出最大调用堆栈大小”错误。将数据从父母传递给孩子失败

Vue.js “超出最大调用堆栈大小”错误。为孩子使用对话框并将数据从父母传递给孩子失败

VueJS/VueX 超出最大调用堆栈大小