Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

So i have a problem when i tried to save file from server response.

When i try to download the file from url in my browser all work but when i tried to send request from the clint side the file is saved but in the file there is "[Object object]" and if it's a PDF file does not open.

The request must include an additional header that contains the key ID of the client.

Here my server code :

        [HttpGet, IsAllowed(4,PageAction.Download)]
    public HttpResponseMessage Download(string id)
    {
        var path = HttpContext.Current.Server.MapPath("~") + string.Format(@"Files\{0}.doc",id);
        var stream = new FileStream(path, FileMode.Open);
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");            
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        result.Content.Headers.ContentDisposition.FileName = string.Format("{0}.doc", id);
        return result;
    }

And here my clint code :

 function get() {
    var defer = $q.defer();

    $http.post('http://localhost:4704/api/file/download/1', { responseType: 'arrayBuffer' }).then(
        function (data, status, headers, config) {
            var results = {
                data: data,
                headers: data.headers(),
                status: data.status,
                config: data.config
            };
            defer.resolve(results);

        }, function (data, status, headers, config) {
            defer.reject(data);
        });
    return defer.promise;
}


$scope.download = function () {

    get().then(function (response) {
        var octetStreamMime = 'application/octet-stream';
        var fileName = "Test.doc";
        var contentType = response.headers["content-type"] || octetStreamMime;
        try {
            var blob = new Blob([response.data], { type: contentType });
            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveOrOpenBlob(blob, fileName);
            } else {
                var objectUrl = URL.createObjectURL(blob);
                window.open(objectUrl);
            }
        } catch (exc) {
            console.log("Save Blob method failed with the following exception.");
            console.log(exc);
        }

    }, function (error) {

    });

In addition, I also tried the following code:

    $http.get("http://localhost:4704/api/file/download").then(function (res) {
        var anchor = angular.element('<a/>');
        anchor.attr({
            href: 'data:attachment/doc;charset=utf-8,',
            target: '_blank',
            download: 'test.doc'
        })[0].click();
    })
share|improve this question
    
if you are trying to download a file . ur header must have content-type:multipart/form-data . If you are not able to open the pdf file properly, it means that the stream is affected. so you need to figure out in the conversions – Aravind 2 days ago
up vote 0 down vote accepted

The server code is clearly sending binary data in response to an HTTP GET from the client. In that case the client needs to set the XHR to responseType: arraybuffer.

Example HTML

<button ng-click="fetch()">Get file</button>

<a download="{{filename}}" xd-href="data">
  <button>SaveAs {{filename}}</button>
</a>

The HTML creates two buttons. Clicking the first button gets the file from the server. The second button saves the file.

xd-href Directive

app.directive("xdHref", function() {
  return function linkFn (scope, elem, attrs) {
     scope.$watch(attrs.xdHref, function(newVal) {
       newVal && elem.attr("href", newVal);
     });
  };
});

The directive watches the scope property defined by the xd-href attribute and sets the href attribute to the value of that scope property.

Controller

var url = "http://localhost:4704/api/file/download/1";
$scope.fetch = function() {
     $http.get(url, {responseType: "arraybuffer"})
       .then (function (response) {
         var disposition = response.headers("content-disposition");
         var filename = disposition.match(/filename="(\w*.\w*)"/)[1];
         $scope.filename = filename || "f.bin";
         $scope.data = new Blob([response.data]);
     }).catch(function (error) {
         console.log(error);
         throw error;
     });
};

The controller uses an XHR GET method to fetch the file, extracts the filename from the Content-Disposition header, and creates a blob from the response data. It sets download attribute of the <a> tag to the value of the file name and the href attribute to the value of the blob. Clicking on the <a> will cause the browser to open a save dialog box.

share|improve this answer

If the data is in json format you can use this

`

href: 'data:text/plain;charset=utf-8,' + JSON.stringify(data)

`

or you can also use this to encode your data,try this

`

href: 'data:text/plain;charset=utf-8,' + encodeURIComponent(data)

`

share|improve this answer
    
Thanks for the help but it did not solve the problem ... – G.Refael 2 days ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.