如何使用webapi中的axios.post下载文件

时间:2017-01-31 04:27:46

标签: reactjs asp.net-web-api axios

我有一个复杂的对象参数,我需要作为post发送,因为它可能对于查询字符串来说太长了。后调用要求动态生成excel文件,然后异步下载。但所有这一切都发生在反应应用程序中。如何使用axios.post,react和webapi做到这一点?我已经确认该文件确实生成了并且响应的下载确实回来了,但我不确定如何实际打开该文件。我有一个隐藏的iframe,我试图设置文件的路径,src,但我不知道要使用什么响应属性。

// webapi
[HttpPost]
public HttpResponseMessage Post([FromBody]ExcelExportModel pModel)
{
    var lFile = ProductDataModel.GetHoldingsExport(pModel);
    var lResult = new HttpResponseMessage(HttpStatusCode.OK);
    lResult.Content = new ByteArrayContent(lFile);
    lResult.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "HoldingsGridExport.xls"
    };

    lResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

    return lResult;
}

// client side api
static getHoldingsExport({ UserConfigurationID, UserID, Configurations, ViewName, SortModel, FilterModel, UserConfigType, IsDefault, LastPortfolioSearchID = null, ProductId }) {
    const filterModel = JSON.stringify(FilterModel); // saving as string as this model is dynamically generated by grid out of my control
    const sortModel = JSON.stringify(SortModel);

    let params = JSON.stringify({
        UserConfigurationID,
        UserID,
        Configurations,
        ViewName,
        filterModel,
        sortModel,
        UserConfigType,
        IsDefault,
        LastPortfolioSearchID,
        ProductId
    });

    return axiosInstance.post("/api/HoldingsExport", params);
}

// client side app call to get file
HoldingsApi.getHoldingsExport(config)
    .then(function(response) {
        debugger;
        let test = response;
    })
    .catch(error => {
        toastr.success('Failed to get export.');
    });

2 个答案:

答案 0 :(得分:3)

这是我通过Axios POSTing实现文件下载的方式:

Axios.post("YOUR API URI", {
    // include your additional POSTed data here
    responseType: "blob"
}).then((response) => {
    let blob = new Blob([response.data], { type: extractContentType(response) }),
        downloadUrl = window.URL.createObjectURL(blob),
        filename = "",
        disposition = response.headers["content-disposition"];

    if (disposition && disposition.indexOf("attachment") !== -1) {
        let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,
            matches = filenameRegex.exec(disposition);

        if (matches != null && matches[1]) {
            filename = matches[1].replace(/['"]/g, "");
        }
    }

    let a = document.createElement("a");
    if (typeof a.download === "undefined") {
        window.location.href = downloadUrl;
    } else {
        a.href = downloadUrl;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
    }
}).catch((error) => {
    // ...
});

答案 1 :(得分:0)

以防万一上述解决方案不能很好地为您服务,这里是我如何能够下载托管在 S3 AWS 存储桶上的视频,

const handleDownload = () => {
    const link = document.createElement("a");
    link.target = "_blank";
    link.download = "YOUR_FILE_NAME"
    axios
      .get(url, {
        responseType: "blob",
      })
      .then((res) => {
        link.href = URL.createObjectURL(
          new Blob([res.data], { type: "video/mp4" })
        );
        link.click();
      });
  };

然后我使用 onClick 在按钮中触发 handleDownload 功能。

函数中的 url 包含来自 S3 存储桶的视频 URL