我使用axios的基本http请求,如GET和POST,它工作得很好。现在我需要能够下载Excel文件。这在axios中可行吗?如果是,谁有一些示例代码?如果不是,我还可以在React应用程序中使用什么来做同样的事情?
当前回答
我有一个问题,我从axios const axiosResponse = await axios.get(pdf.url)传输到谷歌驱动器googleDrive.files。create({media: {body: axiosResponse.)data, mimeType}, requestBody: {name: fileName, parents: [parentFolder], mimeType}, auth: jwtClient})上传一个损坏的文件。
文件损坏的原因是axios转换了axiosResponse。数据转换为字符串。为了解决这个问题,我必须要求axios返回一个axios.get流。url, {responseType: 'stream'})。
其他回答
这是为用户触发下载的非常简单的javascript代码:
window.open("<insert URL here>")
这个操作不需要axios;它应该是标准的,只是让浏览器做它的事情。
注意:如果您需要授权下载,那么这可能无法工作。我很确定你可以使用cookie来授权这样的请求,前提是它在同一个域中,但不管怎样,在这种情况下,这可能不会立即起作用。
至于是否可能……没有内置的文件下载机制,没有。
我有一个问题,我从axios const axiosResponse = await axios.get(pdf.url)传输到谷歌驱动器googleDrive.files。create({media: {body: axiosResponse.)data, mimeType}, requestBody: {name: fileName, parents: [parentFolder], mimeType}, auth: jwtClient})上传一个损坏的文件。
文件损坏的原因是axios转换了axiosResponse。数据转换为字符串。为了解决这个问题,我必须要求axios返回一个axios.get流。url, {responseType: 'stream'})。
诀窍是在render()中创建一个不可见的锚标记,并添加一个React ref,允许在我们有axios响应时触发单击:
class Example extends Component {
state = {
ref: React.createRef()
}
exportCSV = () => {
axios.get(
'/app/export'
).then(response => {
let blob = new Blob([response.data], {type: 'application/octet-stream'})
let ref = this.state.ref
ref.current.href = URL.createObjectURL(blob)
ref.current.download = 'data.csv'
ref.current.click()
})
}
render(){
return(
<div>
<a style={{display: 'none'}} href='empty' ref={this.state.ref}>ref</a>
<button onClick={this.exportCSV}>Export CSV</button>
</div>
)
}
}
以下是文档:https://reactjs.org/docs/refs-and-the-dom.html。你可以在这里找到类似的想法:https://thewebtier.com/snippets/download-files-with-axios/。
下载文件(使用Axios和Security)
当您希望使用Axios和一些安全手段下载文件时,这实际上更加复杂。为了防止其他人花太多时间来弄清楚这个问题,让我来给你介绍一下。
你需要做三件事:
配置您的服务器以允许浏览器看到所需的HTTP报头 实现服务器端服务,并使其为下载的文件发布正确的文件类型。 实现Axios处理程序以在浏览器中触发FileDownload对话框
这些步骤大部分都是可行的——但是由于浏览器与CORS的关系而变得相当复杂。一步一个脚印:
1. 配置您的HTTP服务器
当使用传输安全性时,在浏览器中执行的JavaScript(根据设计)只能访问HTTP服务器实际发送的6个HTTP头。如果我们想让服务器为下载建议一个文件名,我们必须通知浏览器,它是“OK”的JavaScript被授予访问其他头,建议的文件名将被传输。
为了便于讨论,让我们假设服务器在一个名为X-Suggested-Filename的HTTP报头中传输建议的文件名。HTTP服务器告诉浏览器,可以将接收到的自定义报头公开给JavaScript/Axios,报头如下:
Access-Control-Expose-Headers: X-Suggested-Filename
配置HTTP服务器来设置此标头的确切方式因产品而异。
有关这些标准标头的完整解释和详细描述,请参见https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers。
2. 实现服务器端服务
您的服务器端服务实现现在必须执行两件事:
创建(二进制)文档并将正确的ContentType分配给响应 为客户端分配包含建议文件名的自定义头文件(X-Suggested-Filename)
这取决于您选择的技术堆栈,以不同的方式完成。我将草拟一个使用JavaEE 7标准的示例,它应该发出一个Excel报告:
@GET
@Path("/report/excel")
@Produces("application/vnd.ms-excel")
public Response getAllergyAndPreferencesReport() {
// Create the document which should be downloaded
final byte[] theDocumentData = ....
// Define a suggested filename
final String filename = ...
// Create the JAXRS response
// Don't forget to include the filename in 2 HTTP headers:
//
// a) The standard 'Content-Disposition' one, and
// b) The custom 'X-Suggested-Filename'
//
final Response.ResponseBuilder builder = Response.ok(
theDocumentData, "application/vnd.ms-excel")
.header("X-Suggested-Filename", fileName);
builder.header("Content-Disposition", "attachment; filename=" + fileName);
// All Done.
return builder.build();
}
该服务现在发出二进制文档(在本例中是Excel报告),设置正确的内容类型,并发送一个自定义HTTP报头,其中包含保存文档时使用的建议文件名。
3.为Received文档实现一个Axios处理程序
这里有一些陷阱,所以让我们确保所有细节都正确配置:
服务响应@GET(即HTTP GET),因此Axios调用必须是' Axios . GET(…)'。 文档以字节流的形式传输,因此必须告诉Axios将响应视为HTML5 Blob。(例如responseType: 'blob')。 在本例中,文件保护程序JavaScript库用于弹出浏览器对话框。然而,你可以选择另一个。
Axios的框架实现将如下所示:
// Fetch the dynamically generated excel document from the server.
axios.get(resource, {responseType: 'blob'}).then((response) => {
// Log somewhat to show that the browser actually exposes the custom HTTP header
const fileNameHeader = "x-suggested-filename";
const suggestedFileName = response.headers[fileNameHeader];
const effectiveFileName = (suggestedFileName === undefined
? "allergierOchPreferenser.xls"
: suggestedFileName);
console.log(`Received header [${fileNameHeader}]: ${suggestedFileName}, effective fileName: ${effectiveFileName}`);
// Let the user save the file.
FileSaver.saveAs(response.data, effectiveFileName);
}).catch((response) => {
console.error("Could not Download the Excel report from the backend.", response);
});
你需要返回File({file_to_download}, "application/vnd.ms-excel")从后端到前端,在你的js文件中,你需要更新下面写的代码:
function exportToExcel() {
axios.post({path to call your controller}, null,
{
headers:
{
'Content-Disposition': "attachment; filename=XYZ.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
},
responseType: 'arraybuffer',
}
).then((r) => {
const path= window.URL.createObjectURL(new Blob([r.data]));
const link = document.createElement('a');
link.href = path;
link.setAttribute('download', 'XYZ.xlsx');
document.body.appendChild(link);
link.click();
}).catch((error) => console.log(error));
}