При отправке изображений через axios я обнаружил, что должен использовать formdata. Я добавляю сюда свои изображения, но при отправке данных формы весь мой бэкэнд просто зависает, просто говорит «ожидает».
Я следил за этим
И моя попытка до сих пор:
бэкэнд:
Аполлон:
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?
},
}
Внешний интерфейс:
Я строю запрос так:
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
Что я отправляю:
Я точно не понимаю, как данные формы попадут в мою конечную точку преобразователя, и по этой причине я делаю что-то не так, так как бэкэнд возвращается:
(узел: 748) UnhandledPromiseRejectionWarning: [массив объектов] (узел: 748) UnhandledPromiseRejectionWarning: необработанное отклонение обещания. Эта ошибка возникла либо из-за вызова асинхронной функции без блока catch, либо из-за отклонения обещания, которое не было обработано с помощью .catch (). (идентификатор отклонения: 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
запрос отправляется в браузере:
Серверная часть получает данные, но изображение не включено:
РЕДАКТИРОВАТЬ:
Недавно обнаружил, что у моего бэкэнда fastify могут быть проблемы с чтением formData. попытался установить
fastify-multipart
но при регистрации возникли ошибки:
FST_ERR_CTP_ALREADY_PRESENT (contentType) ^ FastifyError [FST_ERR_CTP_ALREADY_PRESENT]:
После этого я попробовал:
npm uninstall fastify-file-upload
Ошибка осталась.
{ id }
- person xadm   schedule 15.05.2020file
неnull
-ed - person xadm   schedule 15.05.2020Fdata.append('file'...
- почему не 0? .... ИМХО, вы должны разделить проблемы ... получить рабочий рецепт клиента (1-я ссылка) и заставить работать бэкэнд ... затем воссоздать его с необходимыми настройками ... слишком много изменений одновременно - person xadm   schedule 15.05.2020mutation name( input ) { result }
- в вашем запросе нет части результата (меня не волнует код) ..... начните с примера workimg formData (FE) и докажите, что BE работает ... затем адаптируйте FE под свои нужды - person xadm   schedule 16.05.2020operations
- person xadm   schedule 16.05.2020