Gatsby-下载的文件始终损坏

问题描述

我正在尝试在我的“关于”页面添加一个简历按钮,用户可以在其中下载我的简历。

我已经按照文档中的根目录(src/static/myresume.pdf中的说明创建了一个静态文件夹,然后有一个href像这样:

<a href={`myresume.pdf`} download className="btn about-resume-button">Download my CV</a>

文件可以正确下载,但是在尝试打开文件时,文件总是损坏的。我尝试了文档docxpdf,并且遇到了相同的问题。

此刻我正在本地主机上本地运行,但是它仍然可以正常工作。

有什么不对劲的地方吗?

我还从文档中看到,您可以使用gatsby-source-filesystem在GraphQL中查询文件,但是我还不知道该怎么做。

任何帮助将不胜感激!

谢谢

解决方法

您的静态文件夹结构有误。它应位于您的根文件夹(与/src相同的级别)中,而不应位于/src中。理想的结构应如下所示:

/
|-- /.cache
|-- /plugins
|-- /public
|-- /src
    |-- /pages
    |-- /templates
    |-- html.js
|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js

注意:更多详细信息,请参见Gatsby Project structure

修正此结构错误,因为您的href指向正确的URL,所以代码将起作用。


但是,Importing Assets Directly into Files documentation中提到和显示的方法将优化您的代码,因为它将使PDF属于Gatsby环境。

要使用Gatsby文件系统,您需要引用该文件并给它们一个sourceInstanceName。在您的gatsby-config.js中:

{
  resolve: `gatsby-source-filesystem`,options: {
    name: `pdf`,path: `${__dirname}/src/pdf/`,},

注意:此示例假定您的PDF将位于/src/pdf文件夹下。此外,您可以在their documentation中找到有关gatsby-source-filesystem的更多信息。

通过为每个文件创建一个节点,可以使您的/src/pdf文件夹可通过GraphQL查询。下一步是在您的组件/页面中查询它:

import React from "react"
import { useStaticQuery,graphql } from "gatsby"

import Layout from "../components/layout"

const DownloadsPage = () => {
  const data = useStaticQuery(graphql`
    {
      allFile(filter: { sourceInstanceName: { eq: "pdf" } }) {
        edges {
          node {
            publicURL
            name
          }
        }
      }
    }
  `)
  return (
    <Layout>
      <h1>All PDF Downloads</h1>
      <ul>
        {data.allFile.edges.map((file,index) => {
          return (
            <li key={`pdf-${index}`}>
              <a href={file.node.publicURL} download>
                {file.node.name}
              </a>
            </li>
          )
        })}
      </ul>
    </Layout>
  )
}
export default DownloadsPage

基本上与上面的代码段一样,您正在检索sourceInstanceName与“ pdf”匹配的所有文件,并循环浏览它们。查询publicURL节点的File字段将提供可在JavaScript组件,页面和模板中使用的URL。

如果只有以下者,则可以忽略循环并直接指向简历:

      <div>
        <a href={data.allFile.edges[0].file.node.publicURL}>{data.allFile.edges[0].file.node.name}</a>
      </div>