如何解决上传文件时从 graphql 中获取臭名昭著的 400 错误,调试显示在 graphql-upload 中填充的数据
我知道这是一个常见问题,而且我已确保应用发送正确的数据。我什至添加了日志记录以显示字段已正确填充。
我注意到的一件事是我在 parser.once('finish' () => {}) 中的 console.log 没有被调用,这就是“Missing multipart field”错误的来源.任何见解将不胜感激。
progressRequest - operations called {
variables: { file: null,name: 'test' }, query: 'mutation ($file: Upload!,$name: String!) {\n' +
' createDocument(file: $file,name: $name) {\n' +
' id\n' +
' name\n' +
' __typename\n' +
' }\n' +
'}\n'
}
processRequest - map called { '1': [ 'variables.file' ] }
processRequest - map entries [ [ '1',[ 'variables.file' ] ] ]
processRequest - map complete Map(1) {
'1' => Upload {
resolve: [Function (anonymous)], reject: [Function (anonymous)], promise: Promise { <pending> }
}
}
processRequest - release Map(1) {
'1' => Upload {
resolve: [Function (anonymous)], promise: Promise { [Object] }, file: {
filename: 'file.docx', mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', encoding: '7bit', createReadStream: [Function: createReadStream]
}
}
}
BadRequestError: Missing multipart field ‘operations’ (https://github.com/jaydenseric/graphql-multipart-request-spec).
客户帖子有以下内容:
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW
Content-Disposition: form-data; name="operations"
{"variables":{"file":null,"name":"test"},"query":"mutation ($file: Upload!,$name: String!) {\n createDocument(file: $file,name: $name) {\n id\n name\n __typename\n }\n}\n"}
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW
Content-Disposition: form-data; name="map"
{"1":["variables.file"]}
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW
Content-Disposition: form-data; name="1"; filename="file.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW--
服务器打字稿:
import { FileUpload,GraphQLUpload } from "graphql-upload";
import { Mutation,Arg,Resolver } from "type-graphql";
import { Document } from "../Document";
@Resolver(Document)
export class DocumentResolver {
@Mutation(() => Document)
async createDocument(@Arg("name") name: string,@Arg("file",() => GraphQLUpload) file: FileUpload): Promise<Document> {
console.warn(name,file);
return null; // dont care about getting anything back as long as I see my console message
};
}
客户端打字稿:
import { Component } from "@angular/core";
import { Apollo,gql } from "apollo-angular";
@Component({
selector: 'test-page', templateUrl: './test.html'
})
export class TestPageComponent {
constructor(private apollo: Apollo) { }
public onFileSelected(e: any): void {
if (e.target.validity.valid) {
this.serverResponse = {};
this.serverResponseErr = {};
let file = e.target.files[0];
this.loadFileApollo(file);
}
}
public loadFileApollo(file: File): void {
const GRAPHQL_CREATE_TEMPLATE = `
mutation($file: Upload!,$name: String!) {
createDocument(file: $file,name: $name) {
id, name
}
}`;
//
//var ti = { file: file };
this.apollo.mutate<any>({
mutation: gql(GRAPHQL_CREATE_TEMPLATE), variables: { file: file,name: "test" }, context: {
useMultipart: true
}
}).subscribe(x=> console.warn(x));
}
}
HTML:
<div>
Click this button to select a file and immediately upload it to the server
<input class="btn btn-primary" type="file" (change)="onFileSelected($event)"/>
</div>
解决方法
所以问题出在 Apollo 内部的 graphql-upload 实现上。如果您正在自动生成架构,我建议您禁用它们的上传并直接实现 graphql-upload。它们落后了很多版本,并且在两个实现之间发送请求时出现问题。
ApolloServer({ uploads: false });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。