【问题标题】:Download file with a REST request needing headers and giving the content下载带有需要标头并提供内容的 REST 请求的文件
【发布时间】:2014-07-20 00:22:58
【问题描述】:

我正在使用带有 REST API 的 AngularJs。我没有 REST API 的手。 我可以通过发送 REST 请求来使用 API 存储数字对象。 我也可以通过 GET 请求获得它。 请求需要有一些特定的标头。

我的目标是为用户提供“下载并另存为”链接。 现在点击事件我提出请求:

    this.file = function (file) {
        var url = config.domain + 'file/' + file;

        var methods = resource(url, null, { 
            'get': {
                method:'GET', 
                headers:{   'Authorization' : user.auth, 
                            'secret-key' : user.secretkey}
            }
            transformResponse : function(data, headersGetter){
                                    return {content:data}; //transform octet stream into text, angular returns an array containing 1 character per element.
                                },
        });
        return methods;
    };

在返回正文中我有文件内容(见下文)。我想下载它。这怎么可能 ?请注意,我无法将文件存储为 URL。

是否可以打开一个窗口,用良好的标题进行其余调用并保存文件?

编辑

我需要能够很好地处理 50Mo 文件的解决方案。

我拥有的 PDF 文件内容示例:

%PDF-1.7
£´ÅÖçø
2 0 obj
[/ICCBased 3 0 R]
endobj
3 0 obj
<<
/Filter /FlateDecode 
/Length 2596 
/N 3 
>>
stream
xwTSÙϽ7½PÐkhRH
½H.*1   JÀ"6DTpDQ¦2(à£C±"Q±ëDÔqpId­ß¼yïÍß÷~k½ÏÝgï}ÖºüÂLX    ¡XáçÅg`ðlàp³³BøF|Ølø½º         ùû*Ó?Áÿ¹Y"1PçòøÙ\É8=W%·Oɶ4MÎ0JÎ"Y2Vsò,[|öe9ó2<ËsÎâeðäÜ'ã9¾`çø¹2¾&ctI@Æoä±|N6(Ü.æsSdl-c(2-        ãyàHÉ_ðÒ/XÌÏËÅÎÌZ.$§&\SáÏÏMçÅÌ07#â1ØYárfÏüYym²";Ø8980m-m¾(Ô]ü÷v^îDøÃöW~
°¦eµÙúmi]ëP»ýÍ`/²¾u}qº|^RÄâ,g+«ÜÜ\Kk)/èïúC_|ÏR¾Ýïåaxó8t1C^7nfz¦DÄÈÎâpùæøþuü$¾/ED˦L         Lµ[ÈB@øøÃþ¤Ù¹ÚøÐX¥!@~(*     {d+Ðï}ÆGùÍÑûÏþ}W¸LþÈ$cGD2¸QÎìüZ4 E@ê@èÀ¶À¸àA(q`1àD µ ­`'¨u     46ptcà48.Ë`ÜR0)ð
Ì@ÈRt CȲXäCP%CBH@ë R¨ªê¡fè[è(tº
C· Qhúz#0   ¦ÁZ°l³`O8ÁÉð28.·Àp|îOÃàX
?§:¢0ÂFBx$  !«¤i@Ú¤¹H§È[EE1PLÊ⢡V¡6£ªQP¨>ÔUÔ(j
õMFk¢ÍÑÎèt,:.FW Ðè³èô8ú¡c1L&³³³Ó9Æa¦±X¬:Öë
År°bl1¶
{{{;}#âtp¶8_\<N+ÄU
[.....]

【问题讨论】:

  • 我不明白为什么?为什么需要将其作为文本发回而不是添加附件标题?您的客户是否编辑文件? (我假设您在浏览器中运行了 SPA 客户端。)如果您想在浏览器中显示 PDF,您可以使用数据 URL 流式传输 PDF。 stackoverflow.com/questions/12848616/…
  • stackoverflow.com/questions/10473932/… 这是您可以从浏览器强制下载的方法。如果您从那里编辑二进制文件。但是,如果将 /files/xxx?aspect=attachment 存储在服务器上,则添加 /files/xxx?aspect=attachment 作为强制下载的表示会好得多。
  • @inf3rno 我没有精确,但问题是我不能使用 data-url,因为这不是文件的存储方式。
  • 我实际上返回了一些标头,但因为它是一个通过角度进行的休息调用,浏览器不会直接收到响应。
  • 问题是我需要在 REST 请求中提供特定的标头,正如我在问题中所说的那样。使用简单的 HTTP 请求是不可能做到这一点的......

标签: javascript angularjs rest


【解决方案1】:

感谢大家帮助寻找解决方案。

我无法在 javascript 和客户端应用程序中找到令人满意的解决方案。 我将创建一个与 API 通信的代理类。

这将发送带有安全标头的 REST 请求,并将文件内容作为响应。

该类将由 HTTP GET 请求调用,因此由于正确的响应标头,“另存为”过程将很容易管理。

【讨论】:

【解决方案2】:

你可以用这个代替上面的代码:

var url = config.domain + 'file/' + file;
   var parameters = "Authorization=" + user.auth +
                    "&secret-key=" + user.secretkey;
   var reportParameters = url + encodeURIComponent(parameters);
   window.location.assign(reportParameters);

【讨论】:

  • 如何保护reportParameters? (顺便说一句,我想我们已经讨论过这是 cmets。)
  • 正如我所说:I don't have the hand on the REST API
【解决方案3】:

也许你可以做这样的事情?

var a = document.createElement('a');
a.href = 'data:attachment/pdf,' + encodeURI(data);
a.target = '_blank';
a.download = 'filename.pdf';
a.click();

您只需要确保 data 的格式正确,即 IIRC 是 base64。

【讨论】:

  • 如果我这样做,我怎么能确定它总是 base64 ?
  • 另外,它需要处理 0 到 50 个月的文档
  • 这是设计过程的一部分。这是一个解决方案,但您必须确定它是否合适以及它是否会起作用。你得到了 PDF 的二进制数据?将其转换为 Base64 并很好地工作。
  • 我认为最新的 chrome(35.0.1916.114) 中的下载属性已损坏..jsfiddle.net/Ls25L ...无论如何你应该这样做。
  • 很好,这是一个很好的解决方法。我会记住这一点的。谢谢
【解决方案4】:

我认为你可以使用 blob,比如

var content=...the content of your request;
var mypdf = new Blob(content, {type : 'application/pdf'});

并在另一个问题Using HTML5/Javascript to generate and save a file中检查“panzi”的答案

(数组中每个元素一个字符看起来很不错的二进制。可能你不需要转换它。https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data

【讨论】:

  • 我试过这个,结果是 readAsBinaryString,我得到:Uncaught TypeError: Failed to construction 'Blob': The 1st argument is not an array,也没有索引属性。跨度>
  • content 应该是一个数组,所以在你的情况下 var mypdf = new Blob([content], {type : 'application/pdf'});
  • 检查 developer.mozilla.org 页面。内容必须是一个数组,根据您的目标浏览器,您有不同的方法。
  • 它适用于 text/plain,但不适用于 zip(文件无法作为存档打开),也不适用于 pdf(空内容)
  • 在 developer.mozilla.org 链接的第一个示例中检查 oReq.onload = function (oEvent) {。这是您必须提供给 blob 以创建二进制文件的数组(它是一个 Uint8Array)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 2017-04-07
  • 2012-05-17
  • 2017-07-17
相关资源
最近更新 更多