Skip to content

DriveItems Download gives CORS error #16

Closed

Description

@dancampbell691

Hello. I was able to successfully replicate the Browser Sample to download my img file. However, when the Sample is adjusted to get a fileitem, the response is an attempted 302 redirect which fails due to CORS policy (per the error message). Given that the URL for the download shouldn't require authorization, this is surprising.

call:
client
.api('/drive/items/' + FileId + '/content')
.responseType('blob')
.get((err, res, rawResponse) => {
if (err) {
console.log(err);
return;
}
console.log(res);
});

Response:
XMLHttpRequest cannot load https://graph.microsoft.com/v1.0/drive/items/01YBCTP6ZQ/content. Redirect from 'https://graph.microsoft.com/v1.0/drive/items/01YBCTP6ZQ/content' to 'https://anonymized.sharepoint.com/_layouts/15/download.aspx?guestaccess…iration=2016-12-05T17%3a23%3a21.000Z&userid=30&authurl=True&NeverAuth=True' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.

Am I missing something, or does the API not support downloading FileItems?

Thanks.

Activity

  1. dan-silver commented on Dec 5, 2016

    @dan-silver
    Contributor

    Hey dancampbell691!

    Are you trying to download the file and parse the response in the browser, or send the file to the user so it appears in their downloaded files list?

    If you want the browser to handle a normal file download, I got the following to work based on this stack overflow answer. I used the SDK to get the file data and sent the downloadUrl value to the iframe to trigger the file download.

    function Download(url) {
    	document.getElementById('my_iframe').src = url;
    };
    
    client
    	.api('/me/drive/root/children/test.txt')
    	.get((err, res) => {
    		// check if there's no error, then
    		Download(res['@microsoft.graph.downloadUrl']);
    	});
  2. self-assigned this
    on Dec 5, 2016
  3. dancampbell691 commented on Dec 5, 2016

    @dancampbell691
    Author

    Hi. Thanks for the quick response. I'm trying to get a PDF then display it, which I do through PDFObject.js.

    I actually just came up with this work around a few minutes before your response. I use Fetch to get the file, put it in an objectURL, then send that to PDFObject. Fetch seems to handle CORS issue.

    client
    .api('/drive/items/' + FileId)
    .get((err, res) => {
        if (err) {
            console.log(err);
            return;
        }
        console.log(res);
        if (res) {
            //use Fetch to overcome CORS issue 
            fetch(res['@microsoft.graph.downloadUrl'])
            .then(function (response) {
                return response.blob();
            })
            .then(function (blobResponse) {
                var objectURL = URL.createObjectURL(blobResponse);
                PDFObject.embed(objectURL, div, PDFOptions);
            });
        }
    });
    

    FYI, the PDFObject component isn't really important. I initially was doing it with the object method of displaying a PDF.

    This is working well enough for me. So unless my code above points you to an issue, I suppose we should call this closed.

    Thanks,
    Dan

  4. dan-silver commented on Dec 5, 2016

    @dan-silver
    Contributor

    Glad it's working! Using fetch is a great idea. If you don't want your code split between promises and callbacks, you can also call .get() with no params and it should return a promise.

    Please re-open this issue if you find any other issues with downloading files with the SDK.

  5. AnoXDD commented on May 30, 2017

    @AnoXDD

    Hi dan-silver ,

    Thanks for the tips on getting the download link of the item!

    Since it looks like Graph will complain if you select("@microsoft.graph.downloadUrl") by saying character '@' is not valid, is there other way around to only get the download link?

    I tried to use Download as described here but Promise failed to follow the redirect link.

  6. dan-silver commented on May 30, 2017

    @dan-silver
    Contributor

    Anoxic (@AnoXDD) Can you try this? I found content.downloadUrl at https://stackoverflow.com/a/39495428/2517012 and tested it with the Graph JS SDK.

     .select("content.downloadUrl")
  7. AnoXDD commented on May 30, 2017

    @AnoXDD

    Thanks for the answer! But unfortunately that doesn't work for me. Would you mind sharing how you tested it?

    My code snippet

     return this.getClient()
            .then(client => {
              return client.api(`me/drive/items/${id}`)
                  .select("content.downloadUrl")
                  .get();
            })
            .then(res => res["content.downloadUrl"]); // <<< and here `res["content.downloadUrl"]` is undefined
    

    It works if I just do

    return this.getClient()
            .then(client => {
              return client.api(`me/drive/items/${id}`)
                  .get();
            })
            .then(res => res["@microsoft.graph.downloadUrl"])
    

    And it is worth noting that this is the old OneDrive API before it was integrated with Graph (and it does start with a @). I used to do so (and it worked) with the old API call, but since Graph doesn't allow @, I guess there really is no way around this.

  8. dan-silver commented on May 30, 2017

    @dan-silver
    Contributor

    I think if you select content.downloadUrl, in the response it's still @microsoft.graph.downloadUrl. In your first code snippet, are there other properties returned on the res object?

    image

    client
        .api('https://graph.microsoft.com/v1.0/me/drive/items/<>')
        .select("content.downloadUrl")
        .get()
        .then((res) => {
            console.log(res['@microsoft.graph.downloadUrl'])
        });
  9. AnoXDD commented on May 30, 2017

    @AnoXDD

    This is very interesting. I run the same way as you did but I didn't get anything

    image

    Even trying to copy and paste the code you provided
    image

    And I'm using token flow and it's on my personal OneDrive, if that makes any difference ...

  10. dan-silver commented on May 31, 2017

    @dan-silver
    Contributor

    Ryan Gregg (@rgregg) Hey Ryan, do you know the proper way to $select the @microsoft.graph.downloadUrl for a drive item? We're seeing it throw character '@' is not valid errors. Is selecting content.downloadUrl an approved workaround? It seems to work for me, but not Anoxic (@AnoXDD) . Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions