Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用$http.get()-OAuth身份验证下载带有Angular的远程文件_Javascript_Ruby On Rails_Angularjs_Amazon S3_Oauth - Fatal编程技术网

Javascript 使用$http.get()-OAuth身份验证下载带有Angular的远程文件

Javascript 使用$http.get()-OAuth身份验证下载带有Angular的远程文件,javascript,ruby-on-rails,angularjs,amazon-s3,oauth,Javascript,Ruby On Rails,Angularjs,Amazon S3,Oauth,我的用户有需要由经过身份验证的用户下载的私人文件。我的服务器首先使用自己的S3应用程序id/secret令牌凭据从S3下载文件。然后使用Rails的方法构造下载的文件并发送给客户端 Ruby(在Rails上): 最初,我想直接从HTML模板进行触发下载 HTML: 是一个使用blob保存文件的简单库(显然是在客户机上) 这使我通过了身份验证问题,但导致文件以不可读/不可用的格式保存/下载到客户端 为什么下载的文件格式不可用? 提前感谢。您好,我举了一个示例,说明如何使用angular从服务器下载

我的用户有需要由经过身份验证的用户下载的私人文件。我的服务器首先使用自己的S3应用程序id/secret令牌凭据从S3下载文件。然后使用Rails的方法构造下载的文件并发送给客户端

Ruby(在Rails上):

最初,我想直接从HTML模板进行触发下载

HTML:

是一个使用blob保存文件的简单库(显然是在客户机上)

这使我通过了身份验证问题,但导致文件以不可读/不可用的格式保存/下载到客户端

为什么下载的文件格式不可用?


提前感谢。

您好,我举了一个示例,说明如何使用angular从服务器下载文件:

我使用GET请求调用该文件:

文件下载html(客户端):


如果您愿意,您可以看到my

Angular的$http方法中的所有代码都需要配置为接受二进制数据响应

Rails的文档:

将给定的二进制数据发送到浏览器。此方法类似于 呈现普通:数据,但也允许您指定浏览器 应将响应显示为文件附件(即在下载中 对话框)或作为内联数据。您还可以设置内容类型 明显的文件名等

Angular的文档对于$http的responseType的配置非常糟糕。本质上,$http需要通过将responseType设置为“arraybuffer”(见下文)来被告知需要一个二进制数据响应

Angular’s可能比以下内容更具描述性:

用法

$http(config)

论据

配置

responseType-{string}-请参阅


我认为您使用javascript解决方案的方向是正确的,但只是有一个输入错误。在
$http.get
调用中,传递一个空对象作为第二个参数。这就是带有
{responseType:arraybuffer}
的options参数应该消失的地方。有关
$http.get
的信息,请参见文档:
$http#get

您必须使用文件保存器吗?您是否尝试过
window.navigator.msSaveOrOpenBlob
window.open(objectUrl)
?我不需要使用FileSaver,但使用window.navigator.msSaveOrOpenBlob和window.open(objectUrl)都会导致相同的问题:无法读取文件格式。仍然是这样的情况,被包装/构造的文件被Blob再次包装/构造。嗨,Ariel,感谢您的响应,但仍然绕过Angular的$http拦截器,因此跳过了身份验证。在我的代码中,我使用了restAngular,但在文件下载的情况下,我不得不这样使用它,因为如果不是,它将返回文件作为后台请求,并且不会下载它。或者,您需要移动到新的url,仅用于GET请求和下载。
# documents_controller.rb
def download
  some_file = SomeFile.find(params[:id])

  # download file from AWS S3 to server
  data = open(some_file.document.url) 

  # construct and send downloaded file to client
  send_data data.read, filename: some_file.document_identifier, disposition: 'inline', stream: 'true'
end
<!-- download-template.html -->
<a target="_self" ng-href="{{ document.download_url }}" download="{{document.file_name}}">Download</a>
<!-- download-template.html -->
<div ng-controller="DocumentCtrl">
  <a ng-click="download(document)">Download</a>
</div>
// DocumentCtrl.js
module.controller( "DocumentCtrl",
  [ "$http", "$scope", "FileSaver", "Blob",
  function( $http, $scope, FileSaver, Blob ) {

    $scope.download = function( document ) {
      $http.get(document.download_url, {}, { responseType: "arraybuffer" } )
        .success( function( data ) {
          var blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" });
          FileSaver.saveAs(blob, document.file_name);
        });
    };
}]);
<a ng-href="/api/downloadFile/{{download.id}}" type="submit" class="btn btn-primary col-lg-12 btn-modal-costume" >download</a>
public static Result download(String id) {
        String content = null;
        for (controllers.file file : files) {
            if (file.getId().equals(id)){
                content = file.getContent();
            }
        }
        return ok(new java.io.File("/temp/" + id+ "file" + content)).as("application/force-download");
    }
$scope.download = function( document ) {
  console.log("download: ", document);
  $http({
    url: document.download_url,
    method: "GET",
    headers: {
      "Content-type": "application/json"
    },
    responseType: "arraybuffer" // expect to handle binary data response
  }).success( function( data, status, headers ) {
      var type = headers('Content-Type');
      var blob = new Blob([data], { type: type });
      FileSaver.saveAs(blob, document.file_name);
    });
};