下载大文件或显示错误

时间:2016-07-21 14:51:54

标签: javascript html iframe xmlhttprequest fileapi

在我们正在处理的网站上,我们有一个下载链接,必须提供给用户。但是,在获取URL时,服务器可以在JSON中提供错误消息(然后将设置相应的标头和相应的http状态代码)或提供文件。

目前,我们正在使用iframe下载此文件,但这会阻止我们查看错误消息。虽然这可以在原则上完成,但它不能跨域完成,并且读取错误数据似乎在浏览器之间不同(因为浏览器会将json解释为html并在其周围创建html标签)

我考虑使用xmlhttprequest2下载文件,并将其提供给用户,但是下载的文件可能很大,因此必须将其传输给用户。

因此,我正在寻找一种方法来下载文件或根据http状态代码读取错误消息。

API设置

我可以根据自己的意愿更改API,但API设计为公共API,并设计为REST API。这意味着API应该尽可能简单,并且使特定客户端代码工作的变通方法不应该导致其他客户端的任何问题(因此API和客户端代码是分离的)。

正在下载的文件在服务器上加密,并且只能通过URL中提供的信息进行解密。因此,分块传输很困难,因为提取块需要服务器解密整个文件。

3 个答案:

答案 0 :(得分:3)

  

然后将设置适当的标头和适当的http状态代码

如果该声明正确,您可以使用与preflighted requests相同的概念进行跨站点请求。预检请求首先使用OPTIONS方法将HTTP请求发送到另一个域上的资源,以确定实际请求是否可以安全发送。

在您的情况下,您可以手动发送OPTIONS请求,而不是自动发送HEAD请求。 HEAD方法与GET相同,只是服务器不在响应中返回消息正文。响应HEAD请求的HTTP标头中包含的信息应与响应GET请求时发送的信息相同。由于您只提取标题而不是正文,因此对于大文件甚至任何文件都没有任何问题,除了标题之外不会下载任何内容。

然后,您可以阅读这些标题甚至状态代码,并根据此手动预检请求的结果,决定是将文件流式传输给用户还是在遇到错误消息时获取错误消息错误。

使用状态代码时不了解项目的基本实现可能如下:

function canDownloadFile(url, callback)
{
  var http = new XMLHttpRequest();
  http.open('HEAD', url);
  http.onreadystatechange = function() {
    if (http.readyState === XMLHttpRequest.DONE) {
      callback(http.status);
    }
  };

  http.send();
}

var canDownloadCallback = function (statusCode) {
  if (statusCode === 200) {
    // The HEAD request returned an OK status code, the GET will do the same,
    // let's download the file...
  } else {
    // The HEAD request returned something else, something is wrong,
    // let's fetch the error message and maybe display it...
  }
}

答案 1 :(得分:1)

您可以返回iframe JS代码,该代码将通过postMessage将消息发送到父窗口,这样您就可以捕获主机窗口中的错误。跨域不会有任何问题,内容很容易像以前一样流式传输到浏览器。

答案 2 :(得分:0)

您可以使用单个请求,将回复作为time.strftime('%m/%d/%Y', time.gmtime(os.path.getmtime(file))) 返回,请检查Blob以确定从Blob.type FileReader使用.result来检索JSON文本的位置{ {1}}并显示错误消息,或使用Blob设置src元素的<img>

URL.createObjectURL

plnkr http://plnkr.co/edit/wrzLNm1Sp4k1mfNrYOlQ?p=preview