我使用axios的基本http请求,如GET和POST,它工作得很好。现在我需要能够下载Excel文件。这在axios中可行吗?如果是,谁有一些示例代码?如果不是,我还可以在React应用程序中使用什么来做同样的事情?
当前回答
下载带有Axios的文件作为responseType: 'blob' 使用Axios/Server响应中的blob创建文件链接 创建<a> HTML元素,使用href链接到步骤2中创建的文件链接,并单击该链接 清理动态创建的文件链接和HTML元素
axios({
url: 'http://api.dev/file-download', //your url
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
// create file link in browser's memory
const href = URL.createObjectURL(response.data);
// create "a" HTML element with href to file & click
const link = document.createElement('a');
link.href = href;
link.setAttribute('download', 'file.pdf'); //or any other extension
document.body.appendChild(link);
link.click();
// clean up "a" element & remove ObjectURL
document.body.removeChild(link);
URL.revokeObjectURL(href);
});
在https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743上查看这些怪癖
全部演职员表发送至:https://gist.github.com/javilobo8
URL的更多文档。createObjectURL在MDN上可用。释放带有URL的对象非常关键。revokeObjectURL防止内存泄漏。在上面的函数中,因为我们已经下载了文件,所以可以立即撤销对象。
每次调用createObjectURL()时,都会创建一个新的对象URL,即使您已经为同一个对象创建了一个URL。当你不再需要它们时,必须调用URL.revokeObjectURL()来释放它们。
当文档被卸载时,浏览器会自动释放对象url;但是,为了优化性能和内存使用,如果存在可以显式卸载它们的安全时间,则应该这样做。
其他回答
对于axios POST请求,请求应该是这样的: 这里的关键是responseType和header字段必须在Post的第3个参数中。第二个参数是应用程序参数。
export const requestDownloadReport = (requestParams) => async dispatch => {
let response = null;
try {
response = await frontEndApi.post('createPdf', {
requestParams: requestParams,
},
{
responseType: 'arraybuffer', // important...because we need to convert it to a blob. If we don't specify this, response.data will be the raw data. It cannot be converted to blob directly.
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf'
}
});
}
catch(err) {
console.log('[requestDownloadReport][ERROR]', err);
return err
}
return response;
}
对于那些想要实现经过身份验证的本地下载的人。
我目前正在使用Axios开发一个SPA。 不幸的是,Axios在这种情况下不允许流响应类型。 从文档:
// `responseType` indicates the type of data that the server will respond with
// options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
// browser only: 'blob'
但我想出了一个解决办法,就像在这个话题中提到的那样。 诀窍是发送一个包含令牌和目标文件的基本Form POST。
这是针对一个新的窗口。一旦浏览器读取服务器响应上的附件标头,它将关闭新选项卡并开始下载。”
下面是一个例子:
let form = document.createElement('form');
form.method = 'post';
form.target = '_blank';
form.action = `${API_URL}/${targetedResource}`;
form.innerHTML = `'<input type="hidden" name="jwtToken" value="${jwtToken}">'`;
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
“您可能需要将处理程序标记为未验证/匿名,以便手动验证JWT以确保适当的授权。”
结果是我的ASP。NET实现:
[AllowAnonymous]
[HttpPost("{targetedResource}")]
public async Task<IActionResult> GetFile(string targetedResource, [FromForm] string jwtToken)
{
var jsonWebTokenHandler = new JsonWebTokenHandler();
var validationParameters = new TokenValidationParameters()
{
// Your token validation parameters here
};
var tokenValidationResult = jsonWebTokenHandler.ValidateToken(jwtToken, validationParameters);
if (!tokenValidationResult.IsValid)
{
return Unauthorized();
}
// Your file upload implementation here
}
我的答案是一个完全hack-我只是创建了一个链接,看起来像一个按钮,并添加URL到它。
<a class="el-button"
style="color: white; background-color: #58B7FF;"
:href="<YOUR URL ENDPOINT HERE>"
:download="<FILE NAME NERE>">
<i class="fa fa-file-excel-o"></i> Excel
</a>
我使用的是优秀的VueJs,因此使用了奇怪的表意,然而,这个解决方案是框架不可知的。这个想法适用于任何基于HTML的设计。
这对我很管用。我在reactJS中实现了这个解决方案
const requestOptions = {`enter code here`
method: 'GET',
headers: { 'Content-Type': 'application/json' }
};
fetch(`${url}`, requestOptions)
.then((res) => {
return res.blob();
})
.then((blob) => {
const href = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = href;
link.setAttribute('download', 'config.json'); //or any other extension
document.body.appendChild(link);
link.click();
})
.catch((err) => {
return Promise.reject({ Error: 'Something Went Wrong', err });
})
文件下载自定义头请求。在这个例子中,它展示了如何用承载令牌发送文件下载请求。适合授权下载内容。
下载(urlHere) { axios。get (urlHere, { 标题:{ “Access-Control-Allow-Origin”:“*”, 授权:'持有人${sessionStorage.getItem("auth-token")} ', } }).then((response) => { const temp = window.URL。createObjectURL(新团([response.data])); const link = document.createElement('a'); 链接。Href = temp; 链接。setAttribute(“下载”,“file.csv”);//或任何其他扩展 document.body.appendChild(链接); link.click (); }); }