如何通过axios上传图像以固定+ graphql后端?

问题描述 投票:1回答:2

通过axios发送图像时,我发现必须使用formdata。我在此处添加图像,但是在发送formdata时,我的整个后端都冻结了,只是说“待定”。

已经关注this

以及到目前为止我的尝试:

后端:

阿波罗:

import { ApolloServer, makeExecutableSchema } from 'apollo-server-fastify';

const schema = makeExecutableSchema({ typeDefs, resolvers });

const apolloServer = new ApolloServer({
  schema,
  uploads: {
    maxFileSize: 10000000,
    maxFiles: 5,
  },
});

(async function() {
  app.register(apolloServer.createHandler({ path: '/api' }));
})();

模式:

  scalar DateTime
  scalar Upload

  input addUser {
    Email: String!
    Password: String
    FirstName: String!
    LastName: String!
    Age: DateTime!
    JobTitle: String!
    File: Upload
  }

  type Mutation {
    register(input: addUser!): Boolean
  }

解析器:

  Mutation: {
    register: async (obj, args, context, info) => {
        // how to get the formData?
      },
  }

FrontEnd:

我建立这样的请求:

const getMutation = (mutate: MutationNames, returParams?: any): any => {
  const mutation = {
    login: print(
      gql`
        mutation($email: String!, $password: String!) {
          login(email: $email, password: $password) {
            token
            refreshToken
          }
        }
      `
    ),
    register: print(
      gql`
        mutation(
          $firstName: String!
          $email: String!
          $lastName: String!
          $age: DateTime!
          $jobTitle: String!
          $file: Upload
        ) {
          register(
            input: {
              FirstName: $firstName
              LastName: $lastName
              Email: $email
              Age: $age
              JobTitle: $jobTitle
              File: $file
            }
          )
        }
      `
    ),

  }[mutate];

  if (!mutation) return {};

  return mutation;
};

在这种情况下,我使用寄存器突变。

我对如何处理数据提取有一些迷惑,因此我不会包含它,因为它包含很多代码。数据是在前端正确提取的,并且在发布到后端之前将所有内容都放入formData对象中:

  const submitForm: SubmitForm = (obj: SendObject) => {
    const Fdata = new FormData();

    Fdata.append('0', fileImp.file);

    Fdata.append('operations', JSON.stringify(obj.data));

    const map = {
      '0': ['variables.file'],
    };
    Fdata.append('map', JSON.stringify(map));

    callAxiosFn(
      {
        method,
        url: 'http://localhost:4000/api',
        data: Fdata,
        // headers: obj.headers,
      },
      qlType.toString()
    );
  };

被这样称呼:

  const response = await axios({
    headers: {
      Accept: 'application/json',
      'x-token': localStorage.getItem('token'),
      'x-refresh-token': localStorage.getItem('refreshToken'),
      ...(config.headers || {}),
    },
    ...config,
  });

配置为AxiosRequestConfig

我发送的内容:

enter image description here

我不完全了解formdata将如何命中我的解析器端点,因此由于后端返回,我做错了什么:

((node:748)UnhandledPromiseRejectionWarning:[对象数组](node:748)UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这个由抛出异步函数引起的错误没有障碍,或者拒绝了没有处理的承诺使用.catch()。 (拒绝ID:1)(节点:748)[DEP0018]DeprecationWarning:已弃用未处理的承诺拒绝。在未来,未处理的承诺拒绝将终止具有非零退出代码的Node.js进程。

我意识到这很多,但是我在这里结束了我的工作,整整一天都在这里。任何帮助深表感谢。

编辑:

由于我的后端受到质疑,我以为我只显示出在不像上面那样附加Formdata的情况下发送数据时,它就可以正常工作:

  const submitForm: SubmitForm = (obj: SendObject) => {

    callAxiosFn(
      {
        method,
        url: 'http://localhost:4000/api',
        data: obj.data,
      },
      qlType.toString()
    );
  };

obj.data是:

{query: "mutation ($firstName: String!, $email: String!, $l… Age: $age, JobTitle: $jobTitle, File: $file})↵}↵", variables: {…}}
query: "mutation ($firstName: String!, $email: String!, $lastName: String!, $age: DateTime!, $jobTitle: String!, $file: Upload) {↵  register(input: {FirstName: $firstName, LastName: $lastName, Email: $email, Age: $age, JobTitle: $jobTitle, File: $file})↵}↵"
variables:
age: "1977-04-04"
email: "[email protected]"
file: File {name: "something.jpg", lastModified: 1589557760497, lastModifiedDate: Fri May 15 2020 17:49:20 GMT+0200 (centraleuropeisk sommartid), webkitRelativePath: "", size: 32355, …}
firstName: "Jhon"
jobTitle: "SomethingCool"
lastName: "Doe"
password: "CoolPassword!"123"
__proto__: Object
__proto__: Object

查询在浏览器中发送:

enter image description here

后端接收数据,但不包括图像:enter image description here

编辑:

[最近发现我的fastify后端可能在读取formData时遇到问题。尝试安装

fastify-multipart

但是注册时出错:

FST_ERR_CTP_ALREADY_PRESENT(contentType)^ FastifyError[FST_ERR_CTP_ALREADY_PRESENT]:

此后,我尝试:

npm uninstall fastify-file-upload

仍然存在错误。

node.js graphql axios apollo-server fastify
2个回答
1
投票

嗯,我还没有探讨这个话题。但是我知道带有[[GraphQL的axios确实不能很好地工作。 Axios主要用于REST API调用。但是,我非常喜欢这个频道Ben Awad,并从中学到了很多东西。这个家伙真是太棒了,他说的东西很清楚很友善。但是最重​​要的是,他是GraphQL的狂热者,并通过React.jsTypeORMPostgreSQL探索并提出了各种主题。以下是他频道中的一些有用链接,它们可能会对您的问题有所帮助:

  • 我希望这会有所帮助!请让我知道内容是否有帮助!

  • 0
    投票
    [这花费了一些时间,通常,当您将某些事情视为理所当然时,发现错误会花费一些时间。

    对于任何有相同问题的人,请记住,您添加事项的顺序!

    我做了什么:

    const Fdata = new FormData(); Fdata.append('0', fileImp.file); // NOTICE THIS Fdata.append('operations', JSON.stringify(obj.data)); const map = { // NOTICE THIS '0': ['variables.file'], }; Fdata.append('map', JSON.stringify(map));

    问题:还记得我说的附加顺序很重要吗?很好的情况是在添加文件之后添加了映射。 

    正确的方法:

    const Fdata = new FormData(); Fdata.append('operations', JSON.stringify(obj.data)); const map = { // NOTICE THIS '0': ['variables.file'], }; Fdata.append('map', JSON.stringify(map)); Fdata.append('0', fileImp.file); // NOTICE THIS

    还请注意,在我的问题中,我没有在变量中将文件本身设置为null:

    variables: { file: null, },

    必须这样做。 

    有关更多信息read here

    © www.soinside.com 2019 - 2024. All rights reserved.