如何使用 axios 将文件上传到使用 graphql-upload 实现的 graphql 后端?

Arc*_*chy 3 express graphql axios

我有一个使用expressexpress-graphqlgraphqlgraphql-upload实现的 GraphQL 后端。我的 GraphQL 架构声明如下:

type OProject {
    _id: ID!
    title: String!
    theme: String!
    budget: Float!
    documentation: String!
    date: Date
}

input IProject {
    title: String!
    theme: String!
    budget: Float!
    file: Upload!
}

type Mutations {
    create(data: IProject): OProject
}

type Mutation {
    Project: Mutations
}
Run Code Online (Sandbox Code Playgroud)

我想使用axioscreate/graphql 上向我的 GraphQL API 发出请求。我该怎么办?

Arc*_*chy 8

遵循此处详述的 GraphQL 多部分请求规范您将通过以下方式执行此操作:

  • 创建一个FormData实例并使用以下内容填充它:
    • operations现场,
    • map场,
    • 要上传的文件

创建 FormData 实例

var formData = new FormData();
Run Code Online (Sandbox Code Playgroud)

operations字段:

此字段的值将是包含 GraphQLqueryvariables. 您必须将variables对象中的所有文件字段设置为空,例如:

const query = `
    mutation($project: IProject!) {
        Project { create(data: $project) { _id } }
    }
`;

const project = {
    title: document.getElementById("project-title").value,
    theme: document.getElementById("project-theme").value,
    budget: Number(document.getElementById("project-budget").value),
    file: null
};

const operations = JSON.stringify({ query, variables: { project } });
formData.append("operations", operations);
Run Code Online (Sandbox Code Playgroud)

map字段:

顾名思义,该字段的值将是一个对象的 JSON 字符串,其键是包含文件的 FormData 实例中的字段名称。每个字段的值将是一个包含字符串的数组,该字符串指示variables与值的键对应的文件将绑定到对象中的哪个字段,例如:

const map = {
    "0": ["variables.project.file"]
};
formData.append("map", JSON.stringify(map));
Run Code Online (Sandbox Code Playgroud)

要上传的文件 然后您应该按照map. 在这种情况下;

const map = {
    "0": ["variables.project.file"]
};
formData.append("map", JSON.stringify(map));
Run Code Online (Sandbox Code Playgroud)

就是这样。您现在可以使用 axios 和 FormData 实例向后端发出请求:

const file = document.getElementById("file").files[0];
formData.append("0", file);
Run Code Online (Sandbox Code Playgroud)