GraphQL 文件上传纯 JS “必须提供查询字符串”。

Posted

技术标签:

【中文标题】GraphQL 文件上传纯 JS “必须提供查询字符串”。【英文标题】:GraphQL file upload plain JS "Must provide query string." 【发布时间】:2022-01-18 11:22:12 【问题描述】:

我正在使用纯 JS 将文件上传到 GraphQL API。几个月来我一直在同一个来源做这件事,现在正试图用 NodeJS 在外部实现完全相同的东西。

我的代码如下所示:

const FormData = require('form-data');
const fs = require('fs')
const axios = require('axios')

const payload = generateRequest(input)

axios.post(apiBaseUrl + "/graphql", payload, 
      headers: ...payload.getHeaders()
    ).then(response => 
        let res = response.data
        if (res.data.triggerPcWorkflow.status === 200) 
            console.log("success!")
         else 
            console.error(res.data.triggerPcWorkflow.message)
        
      )
      .catch(err => 
          if (err.response) 
              console.log(err.response.data);
              console.log(err.response.status);
              console.log(err.response.headers);
          
      )

使用generateRequest 函数生成多部分有效负载 (https://github.com/jaydenseric/graphql-multipart-request-spec)。

我有两个相同版本的后端在 localhost:5000mycooldomain.com 上运行。将apiBaseUrl 设置为http://localhost:5000 时,一切正常。但是,只需将 URL 更改为 https://www.mycooldmain.com,我就会收到一个 400 错误, errors: [ message: 'Must provide query string.' ]

顺便说一句:一个简单的query 可以同时处理两个网址...

这是我的generateRequest 函数:

const mutation = `
mutation MyMutation($xyz: String) 
    doSomething(myInput: $xyz) 
        status 
        message
    

`

let sendData = new FormData();
const fileNull = [];
    
// map
files = generateRequestInput.files
let map = ''

for (let i = 0; i < files.length; i++) 
  fileNull.push(null);
  map += `"$i": ["variables.files.$i"], `


map = map.substring(0, map.length-2);
map += ''

// operations
const operations = JSON.stringify(
    query: mutation,
    variables: 
        "xyz": "Hello"
    
  );

// build payload
sendData.append("operations", operations)
sendData.append("map", map)
for (let i = 0; i < files.length; i++) 
    sendData.append(i, files[i]);


return sendData

我知道map 看起来有点丑,但这不是重点(除非是这样)。

有没有人遇到过类似的问题或知道我的错误是什么? 谢谢!

【问题讨论】:

【参考方案1】:

我跳过了axios 依赖,直接用FormData 实现了请求。

下面的代码有效。

function makeRequest(formData, options) 
  formData.submit(options, (err, res) => 
    if (err) 
      console.error(err.message)
      return
     else 
      
      if (res.statusCode < 200 || res.statusCode > 299) 
        console.error(`HTTP status code $res.statusCode`)
      
      
      const body = []
      res.on('data', (chunk) => body.push(chunk))
      res.on('end', () => 
        const resString = Buffer.concat(body).toString()
        console.log(resString)
      )
    
  )


const options = 
  host: 'mycooldomain.com',
  port: 443,
  path: '/graphql',
  method: 'POST',
  protocol: 'https:'


makeRequest(payload, options)

【讨论】:

以上是关于GraphQL 文件上传纯 JS “必须提供查询字符串”。的主要内容,如果未能解决你的问题,请参考以下文章

node.js / react 使用 graphql createReadStream 上传文件不是函数

无法在 Next.js 应用程序中使用 Apollo-client GraphQL 上传文件:缺少 POST 正文

使用 mongoose 将带有 graphql 的文件上传到 mongodb

纯js实现最简单的文件上传(后台使用MultipartFile)

无法使用 GraphQL 和 Apollo 将文件上传到 Strapi

如何在SharePoint 当中使用纯JSOM上传任意二进制文件(小于2MB)