【问题标题】:How can I save a file by clicking on the link如何通过单击链接保存文件
【发布时间】:2022-01-13 20:55:44
【问题描述】:

我正在使用下一个 js。 这是我第一次遇到这样的任务,我在互联网上的所有搜索都没有给出任何结果,我看到的所有示例都没有成功。 有一个包含文件的文件夹,在服务器上我读取它并获得一个包含这些文件名称的数组:

export default function createFile(req, res) {
    if (req.method === "POST") {
       ...
    } else {
      const files = fs.readdirSync(normalize(join(process.cwd(), "files")));
      res.status(200).json(files);
    }
}

在客户端,我接受一个数组并根据文件名动态创建一个链表:

const [dataList, setDataList] = useState(undefined);
useEffect(async () => {
   const data = await fetch("/api/createFile");
   setDataList(await data.json());
}, []);
return (
    <List
        dataSource={dataList}
        renderItem={item => (
            <List.Item>
               <List.Item.Meta
                   // title={<a href={normalize(join(process.cwd(), "files", item))} download>{item}</a>}
                   title={<a onClick={() => click(item)} download>{item}</a>}
                />
             </List.Item>
         )}
    />
);

我的第一个版本,正如预期的那样,没有给出结果,因为我很愚蠢,忘记了客户端无权访问文件系统,并且在下载错误时文件确实不存在。然后我用谷歌搜索了如何解决这个问题,但没有找到合适的解决方案。 然后我尝试在onclick事件上挂一个方法,在该方法中我将文件名返回给服务器,在服务器上我按名称读取文件,并将文件内容返回给客户端,将其转换为blob并创建一个链接并尝试下载

export default function downloadFile(req, res) {
    if (req.method === "POST") {
        const fileContent = fs.readFileSync(normalize(join(process.cwd(), "files", JSON.parse(req.body))), "utf8");
        res.status(200).send(fileContent);
    } else {
        ...
    }
} 
const click = async (file) => {
    const data = await fetch("/api/downloadFile");
    const blob = await data.blob();
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = downloadUrl;
    link.download = file;
    document.body.appendChild(link);
    link.click();
    link.remove();
    //document.body.removeChild(link);
}

在这种情况下,文件已保存,但打开时出错无法打开文件。 我没有找到更多的解决方案,我知道任务似乎不是很困难,但是我在互联网上找到的所有解决方案都没有帮助我,我将感谢您的帮助!

【问题讨论】:

    标签: node.js reactjs next.js


    【解决方案1】:

    我觉得你应该试试js-file-download,比如这个例子:

    import axios from 'axios'
    import fileDownload from 'js-file-download'
     
        ...
    
    handleDownload = (url, filename) => {
      axios.get(url, {
        responseType: 'blob',
      })
      .then((res) => {
        fileDownload(res.data, filename)
      })
    }
     
    ...
    
    <button onClick={() => {this.handleDownload('/api/downloadFile', 'test-download.jpg')
    }}>Download File</button>
    

    【讨论】:

    • 谢谢,我不想使用第三方库,我读了另一个例子,我们在项目中创建一个公用文件夹并将文件保存在那里,然后结果会得到一个静态的地址并将其传递给 href 链接
    猜你喜欢
    • 2011-03-15
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 2013-09-07
    • 1970-01-01
    • 2014-06-05
    相关资源
    最近更新 更多