11

我尝试下载文件。该操作由ajax()POST 请求触发。该请求将JSON 格式的数据发送到控制器。控制器生成文件(字节)并将其发回。

JavaScript:

function getLicenseFile() {
    $.ajax({
        type: 'POST',
        url: '<%=request.getContextPath()%>/licenses/rest/downloadLicenseFile',
        dataType: 'json',
        contentType: 'application/json;charset=UTF-8',
        data: ko.mapping.toJSON(licenseModel),
        success: function (data) {
            console.log("in sucess")
        },
        error:function (xhr, ajaxOptions, thrownError){
            console.log("in error")
        } 
    });
}  

控制器:

@RequestMapping(value = "/licenses/rest/downloadLicenseFile", method = RequestMethod.POST)
@ResponseStatus(value=HttpStatus.OK)
@ResponseBody
public void createLicenseFile(@Valid @RequestBody License license, HttpServletResponse response) throws Exception {

    logger.debug("Contoller License in: "+ license);

    byte[] licensedata = licenseEncodeDefaultService.createLicenseFile(license);
    logger.debug("licenseData: " + new String(licensedata));

    response.setHeader("Content-Disposition", "attachment; filename=\"" + license.getCustomer() + ".license\"");
    response.getOutputStream().write(licensedata);
    response.flushBuffer();
}


问题

  • 浏览器应该打开一个下载框,但它没有发生
  • 响应在错误中处理:ajax 函数部分(但 HTTP 状态为OK

那么我做错了什么或者正确的方法是什么?

4

5 回答 5

17

Just send a URL of file in response and then "visit" it in your success callback.

function getLicenseFile() {
    $.ajax({
        type: 'POST',
        url: '<%=request.getContextPath()%>/licenses/rest/downloadLicenseFile',
        dataType: 'json',
        contentType: 'application/json;charset=UTF-8',
        data: ko.mapping.toJSON(licenseModel),
        success: function (data) {
            window.open(data.fileUrl);
            // or window.location.href = data.fileUrl;
        },
        error:function (xhr, ajaxOptions, thrownError) {
            console.log("in error");
        } 
    });
}

data.fileUrl should be set in response by server to say client where to get the file.

So your server will send a response with JSON like

{
    "fileUrl": "http://mysite.com/files/0123456789"
}
于 2012-11-22T23:02:47.203 回答
8

@will824如您所问,我将发布我自己的解决方案。

我在控制器中使用了一种解决方法,并将文件临时保存在文件 ystem ( /tmp) 中。我将功能分为两步。创建和下载。这不是很好,但对我来说已经足够了。

控制器(创建一个文件,将保存在服务器文件系统上):

@RequestMapping(value = "/licenses/rest", method = RequestMethod.PUT)
@ResponseStatus(value=HttpStatus.OK)
@ResponseBody
public String createLicenseFile(@Valid @RequestBody License license) throws Exception {

    // create encrypted license file and send the name back to view
    String fileName =  licenseEncodeDefaultService.createLicenseFile(license);
    return fileName;

}

控制器(下载文件):

@RequestMapping(value = "/licenses/downloadFile/{file}", method = RequestMethod.GET)
public void downloadLicenseFile(@PathVariable("file") String file, HttpServletResponse response) throws Exception {

    // create full filename and get input stream
    File licenseFile = new File ("/tmp/" + file);
    InputStream is = new FileInputStream(licenseFile);

    // set file as attached data and copy file data to response output stream
    response.setHeader("Content-Disposition", "attachment; filename=\"" + file + ".license\"");
    FileCopyUtils.copy(is, response.getOutputStream());

    // delete file on server file system
    licenseFile.delete();

    // close stream and return to view
    response.flushBuffer();
}

JavaScript:

function getLicenseFile() {
    //console.log(ko.mapping.toJSON(licenseModel));
    $.ajax({
        type : 'PUT',
        url : '${pageContext.request.contextPath}/licenses/rest',
        dataType : 'text',
        contentType : 'application/json;charset=UTF-8',
        data : ko.mapping.toJSON(licenseModel),
        success : function(data) {
            window.location.href = '${pageContext.request.contextPath}/licenses/downloadFile/'
                    + data;
        },
        error : function(xhr, ajaxOptions, thrownError) {
            // error handling
        }
    });
}
于 2013-08-13T09:51:01.037 回答
4

如果您想在不更改 URL 的情况下下载文件,则可以以form.submit() 编程方式调用而不是使用 AJAX。

JavaScript:

function downloadFileUsingForm(url) { 
    var form = document.createElement("form");
    form.method = "post";
    form.action = url;
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
}
downloadFileUsingForm("/YourController/DownloadFile");

控制器:

[HttpPost]
public ActionResult DownloadFile()
{
    string content = "Some Values";
    byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(content);
    return File(bytes, System.Net.Mime.MediaTypeNames.Application.Octet, "file.txt");
}
于 2015-02-05T10:18:04.623 回答
2

正如评论所说,你不能用 ajax 调用来做,但你可以用纯 Javascript 来做。

function getLicenseFile() {
    var downloadUrl = "${pageContext.request.contextPath}/licenses/rest/downloadLicenseFile";
    // (optionally) provide the user with a message that the download is starting
    window.location.href = downloadUrl;
}

注意 的使用${pageContext.request.contextPath},它优于<%=request.getContextPath()%>.

于 2012-11-22T23:04:30.593 回答
0

Ajax 不会帮助您尝试使用隐藏表单方法

<form action='../servletname' method='POST' id='formid'>
                <input type='hidden' value='' name='name' id='id'/>
                <input type='hidden' value=' ' name='name'  id='id' />
            </form>

单击下载按钮提交表单时,通过表单字段向您传递 json

$('#formid').submit();

然后在服务器端

response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=filnemae.fileformat");

 ServletOutputStream out = res.getOutputStream();

写入输出流然后关闭或刷新

如果您通过server.xml 中的 post update postsize发送大数据

于 2017-07-27T13:08:46.953 回答