上传文件时从 graphql 获取臭名昭著的 400 错误,调试显示在 graphql-upload 中填充的数据

Posted

技术标签:

【中文标题】上传文件时从 graphql 获取臭名昭著的 400 错误,调试显示在 graphql-upload 中填充的数据【英文标题】:Getting the infamous 400 error from graphql when uploading a file, debug shows data populated in graphql-upload 【发布时间】:2021-04-29 10:04:18 【问题描述】:

我知道这是一个常见问题,并且我已确保该应用正在发送正确的数据。我什至添加了日志记录以显示字段被正确填充。

我注意到的一件事是我在 parser.once('finish' () => ) 中的 console.log 没有被调用,这应该是“缺少多部分字段”错误的来源.任何见解将不胜感激。

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)],
    reject: [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>

【问题讨论】:

【参考方案1】:

所以问题在于 Apollo 的 graphql-upload 内部实现。如果您要自动生成架构,我建议您禁用它们的上传并直接实施 graphql-upload。它们落后了很多版本,并且在两个实现之间发送请求时遇到问题。

ApolloServer( uploads: false );

【讨论】:

以上是关于上传文件时从 graphql 获取臭名昭著的 400 错误,调试显示在 graphql-upload 中填充的数据的主要内容,如果未能解决你的问题,请参考以下文章

在 BigQuery 上上传和导入数据时从 bq 工具获取错误 - “后端错误”

如何在 hasura graphql 引擎上上传文件或图像

prisma - 运行 graphql 查询时获取环境变量未找到错误消息

App Store 错误:您上传的二进制文件无效

GraphQL js 文件上传

GraphQL:在文件上传期间解决承诺时出错