使用 React.JS (Axios Get) 从 Node.JS API REST (express) 下载文件
Downloading a file from a Node.JS API REST (express) with React.JS (Axios Get)
我有一个 React JS 应用程序,作为后端有一个 API 用 Node JS 制作的 REST。
目前,我的 objective 是能够下载服务器上的文件。
正确的行为应该是用户在单击“下载文件”后应该收到文件(使用浏览器下载)。
在服务器端,我有这样的东西(显然,我将通过删除 JWT 中间件、数据库查询等来简化它):
const express = require('express');
const router = express.Router();
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
app.use(cors({ origin: "http://localhost:3000" }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.get('/download', (req, res, next) => {
res.download("\\folder\subfolder\myfile.txt");
});
app.use('/api', router);
const PORT = 3001;
app.listen(PORT, function() {
console.log("Server is running on port "+PORT);
});
然后,正如我所说,我有一个 React JS 应用程序作为 Frontend:
apihelperdownload () {
return axios.get(API_URL + "download").then(function (response) {
return response;
})
}
.............
function downloadFile() {
apihelperdownload().then(
(res) => {
// Should I do something here with response?
},
(error) => {
}
)
}
<button className="download" onClick={() => downloadFile()}>
Download File
</button>
我的服务器上有两个文件,一个TXT 和一个JPG。
两者都有正确的路径(我没有收到任何“file/path not found”错误)并且在这两种情况下我都收到“200 status OK”...但是我无法下载文件。
还有:
- 在 JPG 的情况下,在网络选项卡中,在预览子选项卡上我可以看到图像(因此浏览器正在接收图像)。
响应如下所示:
(忽略参数和不同的url,只是这里没有简化)
- 在 TXT 的情况下,在网络选项卡中,在预览子选项卡上我只能看到一个白页。
响应如下所示:
如您所见,在第二种情况(.txt 文件)中,数据为“空”( "" )
数据是正确的文本..我没有保存txt文件..所以它是空的..
我查了好几个相关问题都是这样Download a file from NodeJS Server using Express
但不幸的是,我还没有找到解决问题的方法。
1) 我在服务器端做错了什么?
2) 客户端的响应与我有什么关系?
谢谢
您可以使用 js-file-download 模块。
const FileDownload = require('js-file-download');
Axios.get(API_URL + "download")
.then((response) => {
FileDownload(response.data, 'file.txt');
});
查看此回复了解更多信息:
我找到了如何在没有第三方库的情况下以相当“简单的方式”解决它。
首先,我已经将请求更改为POST(因为我认为这是唯一的方法,所以我刚刚进行了GET)。
之后,在 Axios 请求中,我们必须将 responseType 指定为 blob:
function apihelperdownload () {
return axios.post(API_URL + "download",{ key: 'value', headers: authHeader(), responseType: 'blob' }).then(function (response) {
return response;
})
}
然后,当我们收到响应时,我们必须创建一个 URL 对象作为 Blob 和一个 link 元素来下载它。
function downloadFile(filename) {
apihelperdownload().then(
(res) => {
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
if (typeof window.navigator.msSaveBlob === 'function') {
window.navigator.msSaveBlob(
res.data,
filename
);
} else {
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
}
},
(error) => {
alert("Something went wrong");
}
)
}
有了这个,我们可以非常轻松地下载几乎任何类型的文件。
我有一个 React JS 应用程序,作为后端有一个 API 用 Node JS 制作的 REST。
目前,我的 objective 是能够下载服务器上的文件。 正确的行为应该是用户在单击“下载文件”后应该收到文件(使用浏览器下载)。
在服务器端,我有这样的东西(显然,我将通过删除 JWT 中间件、数据库查询等来简化它):
const express = require('express');
const router = express.Router();
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
app.use(cors({ origin: "http://localhost:3000" }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.get('/download', (req, res, next) => {
res.download("\\folder\subfolder\myfile.txt");
});
app.use('/api', router);
const PORT = 3001;
app.listen(PORT, function() {
console.log("Server is running on port "+PORT);
});
然后,正如我所说,我有一个 React JS 应用程序作为 Frontend:
apihelperdownload () {
return axios.get(API_URL + "download").then(function (response) {
return response;
})
}
.............
function downloadFile() {
apihelperdownload().then(
(res) => {
// Should I do something here with response?
},
(error) => {
}
)
}
<button className="download" onClick={() => downloadFile()}>
Download File
</button>
我的服务器上有两个文件,一个TXT 和一个JPG。 两者都有正确的路径(我没有收到任何“file/path not found”错误)并且在这两种情况下我都收到“200 status OK”...但是我无法下载文件。
还有:
- 在 JPG 的情况下,在网络选项卡中,在预览子选项卡上我可以看到图像(因此浏览器正在接收图像)。
响应如下所示:
(忽略参数和不同的url,只是这里没有简化)
- 在 TXT 的情况下,在网络选项卡中,在预览子选项卡上我只能看到一个白页。
响应如下所示:
如您所见,在第二种情况(.txt 文件)中,数据为“空”( "" )
数据是正确的文本..我没有保存txt文件..所以它是空的..
我查了好几个相关问题都是这样Download a file from NodeJS Server using Express
但不幸的是,我还没有找到解决问题的方法。
1) 我在服务器端做错了什么?
2) 客户端的响应与我有什么关系?
谢谢
您可以使用 js-file-download 模块。
const FileDownload = require('js-file-download');
Axios.get(API_URL + "download")
.then((response) => {
FileDownload(response.data, 'file.txt');
});
查看此回复了解更多信息:
我找到了如何在没有第三方库的情况下以相当“简单的方式”解决它。
首先,我已经将请求更改为POST(因为我认为这是唯一的方法,所以我刚刚进行了GET)。
之后,在 Axios 请求中,我们必须将 responseType 指定为 blob:
function apihelperdownload () {
return axios.post(API_URL + "download",{ key: 'value', headers: authHeader(), responseType: 'blob' }).then(function (response) {
return response;
})
}
然后,当我们收到响应时,我们必须创建一个 URL 对象作为 Blob 和一个 link 元素来下载它。
function downloadFile(filename) {
apihelperdownload().then(
(res) => {
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
if (typeof window.navigator.msSaveBlob === 'function') {
window.navigator.msSaveBlob(
res.data,
filename
);
} else {
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
}
},
(error) => {
alert("Something went wrong");
}
)
}
有了这个,我们可以非常轻松地下载几乎任何类型的文件。