如何使用axios上传图像以固定+ graphql后端? [英] How to upload images to fastify + graphql backend with axios?

查看:79
本文介绍了如何使用axios上传图像以固定+ graphql后端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过axios发送图像时,我发现必须使用formdata.我在这里添加图像,但是在发送表单数据时,我的整个后端都死机了,只是说待定".

我一直在关注

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

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

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

由于我的后端受到质疑,我想我将显示在不添加Formdata的情况下发送数据,就像我在上面所做的那样,然后我就可以正常工作了:

  const SubmitForm:SubmitForm =(obj:SendObject)=>{callAxiosFn({方法,网址:"http://localhost:4000/api",数据:obj.data,},qlType.toString());}; 

obj.data是:

  {查询:变异($ firstName:String!,$ email:String!,$ l…年龄:$ age,JobTitle:$ jobTitle,文件:$ file})↵}↵",变量:{…}}查询:变异($ firstName:String!,$ email:String!,$ lastName:String!,$ age:DateTime!,$ jobTitle:String!,$ file:Upload){↵register(input:{FirstName:$firstName,LastName:$ lastName,电子邮件:$ email,年龄:$ age,JobTitle:$ jobTitle,文件:$ file})↵}↵变量:年龄:"1977-04-04"电子邮件:"JhoneDoe@hotmail.com"档案:档案{名称:"something.jpg",lastModified:1589557760497,lastModifiedDate:2020年5月15日星期五格林尼治标准时间+0200(centureuropeisk sommartid),webkitRelativePath:",大小:32355,…}firstName:"Jhon"jobTitle:"SomethingCool"lastName:"Doe"密码:"CoolPassword!" 123__proto__:对象__proto__:对象 

查询在浏览器中发送:

后端接收数据,但不包含图像:

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

  fastify-multipart 

但是注册时出错:

FST_ERR_CTP_ALREADY_PRESENT(contentType)^ FastifyError[FST_ERR_CTP_ALREADY_PRESENT]:

之后,我尝试:

  npm卸载fastify-file-upload 

错误仍然存​​在.

解决方案

这花了一些时间,通常,当您将某些事情视为理所当然时,要花一些时间才能发现错误.

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

我做了什么:

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

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

正确的方法:

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

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

 变量:{文件:null,}, 

这是必须要做的.

有关更多信息,在此处阅读

When sending images via axios I found I have to use formdata. I add my images here but when sending the formdata my entire backend just freezes, just says "pending".

Ive been following this

And my attempt so far:

backend:

Apollo:

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

schema:

  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
  }

resolver:

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

FrontEnd:

I build the request like this:

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

In this case im using the register mutation.

I have a few hooks on how I handle the data fetching so Im not going to include it since it is alot of code. The data is fetched correctly in the front end and before posting to the backend im putting everything to a formData object:

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

gets called like this:

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

config is AxiosRequestConfig

What Im sending:

I dont exactly understand How the formdata will hit my resolver endpoint and for that reason im doing something wrong since the backend returns:

(node:748) UnhandledPromiseRejectionWarning: [object Array] (node:748) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:748) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I realize this is alot but Im at the end of my vits here, been at this the entire day. Any help is deeply appreciated.

EDIT:

Since my backend was questioned I thought I would just show that when sending data without appending Formdata like I do above then I get it working:

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

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

obj.data is:

{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: "JhoneDoe@hotmail.com"
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

query getting sent in the browser:

Backend reciving the data but the image is not included:

EDIT:

Recently found that my fastify backend might have issues with reading formData. tried installing

fastify-multipart

but got errors when registering it:

FST_ERR_CTP_ALREADY_PRESENT(contentType) ^ FastifyError [FST_ERR_CTP_ALREADY_PRESENT]:

After that I tried:

npm uninstall fastify-file-upload

Error remained.

解决方案

This took some time and usally when you take something for granted it takes time to find the mistake.

For anyone having the same problem please remember that the order you add something MATTERS!

What I did:

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

Problem: Remember when I said order of appending things matter? Well the case here was that the mapping was added after the file was added.

The correct way:

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

Also note that in my qestion I missed setting the file itself to null in the variables:

  variables: {
    file: null,
  },

This has to be done.

For more info read here

这篇关于如何使用axios上传图像以固定+ graphql后端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆