首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Redux/Redux下载文件

Redux/Redux下载文件
EN

Stack Overflow用户
提问于 2016-11-02 10:23:55
回答 1查看 14.2K关注 0票数 2

单击按钮时,我需要从服务器下载一个文件。

我创建了一个MaterialUI按钮,在它的onclick回调中,我调用了容器组件连接的一个操作。

该操作是异步的,并执行ajax POST:

代码语言:javascript
复制
export const onXlsxClick = () => dispatch => {
    const urlParams = {
        filters: {
            aggregation: 'macro_area',
            chart_resolution: '1_hour',
            chart_from: '1478080363',
            chart_to: '1477993963'
        },
        labels: ['PROVA1', 'PROVA2'],
        series: [
            {
                label: null,
                timestamp: 1478080363,
                values: [123, 345]
            },
            {
                label: null,
                timestamp: 1477993963,
                values: [153, 3435] 
            }
        ]
    };
    return $.ajax({
        url:'/rest/export/chart/xlsx',
        type: 'POST',
        dataType: 'application/json',
        contentType: 'application/json',
        data: JSON.stringify(urlParams)
    })
    .done(data => {
       console.log('success');
    })
    .fail(error => {
        console.log(error);
    });
};

服务器接收请求并通过这个REST服务正确地处理它:

代码语言:javascript
复制
@POST
@Path("xlsx")
@Produces("application/vnd.ms-excel")
public Response getXlsx(ChartExportRequest request) {
    ResponseBuilder responseBuilder;
    ChartExportRequestDTO reqDto = null;
    try {
        reqDto = parseDTO(request);
        checkRequestDTO(reqDto);
        ExportDTO dto = getXlsxProvider().create(reqDto);

        responseBuilder = Response.ok(dto.getFile())
                .header("Content-disposition", "attachment;filename=" + dto.getFileName());
    }
    catch(Exception e) {
        logger.error("Error providing export xlsx for tab RIGEDI with request [" + (reqDto != null ? reqDto.toString() : null) + "]", e);
        responseBuilder = Response.serverError().entity(e.getMessage());
    }
    return responseBuilder.build();
}

问题是,响应到达客户端是正确的,但随后什么也没有发生:我期望浏览器显示下载对话框(例如:在chrome中,我希望下载的底部显示在我的文件中)。

我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2017-02-15 09:21:15

根据奈特的答案这里,浏览器不能将Ajax请求的响应识别为文件。对于所有Ajax响应,它将以相同的方式运行。您需要手动触发下载弹出。

在我的实现中,我使用文件版本触发下载弹出,一旦我收到了还原器中的API响应。

由于FileSaver使用blob保存文件,所以我将从服务器作为blob发送响应,将其转换为字符串数组缓冲区,然后使用它保存文件。这一方法在

请为还原程序找到下面的示例代码:(使用减速器进行状态修改,如Redux所示) reducer.js

代码语言:javascript
复制
let fileSaver = require("file-saver");


export default function projectReducer(state = {}, action)
{
    let project;
    switch (action.type) {
        case  GET_PROJECT_SUCCESS :
            project = Object.assign(action.response.data);
            return project;
        case EXPORT_AND_DOWNLOAD_DATA_SUCCESS :
            let data = s2ab(action.response.data);
            fileSaver.saveAs(new Blob([data], {type: "application/octet-stream"}), "test.xlsx");
            return state;


    }
    return state;

}

function s2ab(s) {
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i = 0; i != s.length; ++i) {
        view[i] = s.charCodeAt(i) & 0xFF;
    }
    return buf;
}

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40377541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档