2

I want to download a file using REST API.

I have a file in a document library /folder. I want download that file, but with a different name.

Edit 1 : Below is my code. i am able to download file on Chrome browser but data gets corrupted and also not working on IE 10+.

function SaveToDisk_blob(blobURL, fileName)
{
var reader = new FileReader();
console.log(blobURL.body)
console.log(fileName.split(".")[1])
var blob = new Blob([blobURL.body], { type: "application/"+fileName.split(".")[1]+"" });
reader.readAsDataURL(blob);
reader.onload = function (event) {
    var save = document.createElement('a');
    save.href = event.target.result;
    save.target = '_blank';
    save.download = fileName || 'unknown file';

    var event = document.createEvent('Event');
    event.initEvent('click', true, true);
    save.dispatchEvent(event);
    (window.URL || window.webkitURL).revokeObjectURL(save.href);
};
reader.onerror = function (e) {
    console.log(e)
}
}

function downloadFile(url, fileName)
{

// executes cross domain request
var appweburl = _spPageContextInfo.webAbsoluteUrl
$.getScript(appweburl + "/_layouts/15/SP.RequestExecutor.js", function () {
    var executor = new SP.RequestExecutor(appweburl);
    executor.executeAsync(
    {
        url: url,
        type: "GET",
        binaryStringResponseBody: true,
        success: function (blobURL)
        {
            SaveToDisk_blob(blobURL, fileName)
        },
        error: function (xhr)
        {
            console.log(xhr);
            console.log("downloadFile" + xhr.status + ": " + xhr.statusText);

        }
    });
});
}

Edit 2: i have made some more change in code.

function call_to_rest_binarystring(rest_url)
{
    return $.ajax({
    url: rest_url,
    method: "GET",
});
}

function downloadFile(rest_url, filepath, fileName)
{
    var dfd = $.Deferred();
if (!window.ActiveXObject) 
{
    var save = document.createElement('a');
    save.href = filepath;
    save.target = '_blank';
    save.download = fileName || 'unknown';

    var event = document.createEvent('Event');
    event.initEvent('click', true, true);
    save.dispatchEvent(event);
    (window.URL || window.webkitURL).revokeObjectURL(save.href);
    dfd.resolve(true);
}
else if (!!window.ActiveXObject && document.execCommand)
{
    var rest_return_call = call_to_rest_binarystring(rest_url)
    rest_return_call.done(function (response, status, xhr)
    {


        var blob = new Blob([response], { type: "application/" + fileName.split(".")[1] + "" });
        window.navigator.msSaveBlob(blob, fileName);

    });

}
return dfd.promise()
}

var rest_url = "<site name>/_api/web/GetFileByServerRelativeUrl('/ShareDocument/111.pdf')/openbinarystream"

downloadFile(rest_url, filepath, fileName)

still while we download file it is coming blank. i think i am missing something. can anyone help me with this.

  • Are you asking how to retrieve the file, or how to save it? You might get better results on SO for saving the file on disk. As for retrieving a file, google should reveal results like this with instructions on retrieving files. – wjervis Apr 1 '15 at 14:08
  • @Vadim i am able to solve this issue with help of this article link. i am not able to create blob data. – Rahul Dayal Apr 1 '15 at 14:20
  • i am following same link but i am not able to solve this issue. when REST call return data, data does not contains body. i think i am missing something. – Rahul Dayal Apr 1 '15 at 14:23
  • 1
    Can you edit your question with this info? Put the link, the code you have tried, and any error you may have. – wjervis Apr 1 '15 at 14:25
  • @wjervis any update on this. data still get corrupted – Rahul Dayal Apr 2 '15 at 7:44
1

I usually use AttachmentFiles endpoint to do this, it is provided when you create or select Item with API.

<link  rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/AttachmentFiles" type="application/atom+xml;type=feed" title="AttachmentFiles" href="Web/Lists(guid'12f9fd2c-0eea-4440-b9d3-a6e445839ba3')/Items(66)/AttachmentFiles" />

Main part is

href="Web/Lists(guid'12f9fd2c-0eea-4440-b9d3-a6e445839ba3')/Items(66)/AttachmentFiles" 

You can use both

To download      /Items(66)/AttachmentFiles('file.docx')
To upload        /Items(66)/AttachmentFiles/add(FileName='file.docx')

Then u can use a GET method to download file content :

executor.executeAsync(
    {
        url: UsePreviousEndPoint,
        type: "GET",
        contentType: "application/atom+xml;type=entry",
        headers: {
                "Accept": "application/atom+xml",
                "Authorization": "Bearer " + UserOrAppToken
            },      
        success: function (blobURL)
        {
            SaveToDisk_blob(blobURL, fileName)
        },
        error: function (xhr)
        {
            console.log(xhr);
            console.log("downloadFile" + xhr.status + ": " + xhr.statusText);

        }
    });

I guess Digest is only mandatory for POST request.

  • this is not helpfull to me as this code getting data from list attachment, i want to fetch data from document library file. – Rahul Dayal Apr 3 '15 at 7:23
  • @RahulDayal use the url to get the file from the document library then. Other than the url, Albo's code should work. – wjervis Apr 3 '15 at 12:55
  • @wjervis it is not working, when we download file it does not contains any data. blank file. – Rahul Dayal Apr 3 '15 at 13:13
1

below are my final working code for downloading file from REST.

var dfd = $.Deferred();
var xhr = new XMLHttpRequest();
xhr.open("GET", filepath);
xhr.responseType = "blob";
//setting response-type header to be blob so that we get the file as blob
xhr.onload = function ()
{
//async call
var blobobj = xhr.response;
window.navigator.msSaveBlob(blobobj, fileName);
//save using msSaveBlob.
dfd.resolve(true);
}
xhr.send();
return dfd.promise()
0

If you have direct link to the file, then you can use below approach. But the filename will be the same

<script type="text/javascript">
  function download(url) {
    var a = document.createElement('a');        
    a.setAttribute('href', url);        
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }
</script>
  • thanks for reply. but while downloading file i want to change name of the file and code should work on IE and safari browser. above code does not work on IE browser. – Rahul Dayal Apr 1 '15 at 14:26
  • any update on this – Rahul Dayal Apr 2 '15 at 11:16
0

I am not sure about your method. I am using REST and needed to add $value to the URL get the file content, instead of the file metadata.

rc.spActionURL = "https://{mysite}.sharepoint.com/sites/{mysites}/#this.sp365.orisApp#/_api/Web/GetFileByServerRelativeUrl('/sites/{mysites}/#this.sp365.orisApp#/#arguments.libraryPath#/#arguments.folderName#/#arguments.fileName#')/$value";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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