Javascript 下载大文件或显示错误

Javascript 下载大文件或显示错误,javascript,html,iframe,xmlhttprequest,fileapi,Javascript,Html,Iframe,Xmlhttprequest,Fileapi,在我们正在开发的网站上,我们有一个下载链接,必须提供给用户。但是,在获取url时,服务器可以提供JSON格式的错误消息(然后将设置适当的头和适当的http状态代码),也可以提供文件 目前,我们正在使用iframe下载此文件,但这会阻止我们查看错误消息。虽然这在原则上是可以做到的,但不能跨域完成,而且不同浏览器读取错误数据的方式似乎不同(因为浏览器会将json解释为html并在其周围创建html标记) 我已经考虑过使用xmlhttprequest2下载文件,并将其提供给用户,但是下载的文件可能很大

在我们正在开发的网站上,我们有一个下载链接,必须提供给用户。但是,在获取url时,服务器可以提供JSON格式的错误消息(然后将设置适当的头和适当的http状态代码),也可以提供文件

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

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

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

API设置

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

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

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

如果这句话是正确的,您可以使用与跨站点请求相同的概念。预引导请求首先使用
选项
方法向另一个域上的资源发送HTTP请求,以确定实际请求是否可以安全发送

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

然后,您可以读取这些头,甚至是状态代码,并根据此手动预引导请求的结果,决定是否应该将文件流式传输给用户,或者在遇到错误时获取错误消息

使用状态代码而不了解您的项目的基本实现可能是:

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...
  }
}
然后将设置适当的头和适当的http状态代码

如果这句话是正确的,您可以使用与跨站点请求相同的概念。预引导请求首先使用
选项
方法向另一个域上的资源发送HTTP请求,以确定实际请求是否可以安全发送

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

然后,您可以读取这些头,甚至是状态代码,并根据此手动预引导请求的结果,决定是否应该将文件流式传输给用户,或者在遇到错误时获取错误消息

使用状态代码而不了解您的项目的基本实现可能是:

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...
  }
}

您可以使用单个请求,将响应返回为
Blob
,选中
Blob.type
以确定在何处使用
FileReader
。result从
Blob
检索
JSON
文本并显示错误消息,或者使用
URL.createObjectURL


plnkr

您可以使用单个请求,将响应作为
Blob
返回,选中
Blob.type
以确定在何处使用
FileReader
。result从
Blob
检索
JSON
文本并显示错误消息,或者使用
URL.createObjectURL


plnkr

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

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

您可以控制服务器响应吗?您是否可以将响应更改为错误代码和错误消息或成功代码和文件url?如果是这样,您只需进行一个ajax调用,并在成功时重定向到url。如果这不起作用,请解释一下你的设置如何防止这种情况发生。预期的
MIME
文件类型是什么?@TinMonkey,是的,我知道。但一般来说,任何错误都是例外,我宁愿提出一个请求,但我只是