I have an Angular application that is using OneDrive/Sharepoint to store files it has created. Authentication is working correctly and I can save my files successfully. I am having a problem with downloading the file that I created and stored using the Angular HttpClient.
My code looks like this:
export class MicrosoftService {
private graphUri = 'https://graph.microsoft.com/v1.0';
constructor(private http: HttpClient) {}
public loadFile(id: string, next: (saved: string) => void): void {
this.http.get(this.graphUri + '/me/drive/items/' + id + '/content', { headers: this.getOAuthHeader() })
.subscribe((response: any) => {
console.log(response.toString());
next(response.toString());
});
}
getOAuthHeader(): HttpHeaders {
// a bunch of stuff that generates the OAuth headers, definitely works
}
}
Obviously I'll do something else with the response when I can receive it.
The problem is that when the GET
request is triggered it correctly makes a request to graph, which then returns a 302 redirect to https://foozlecorporation-my.sharepoint.com/drive/path/_layouts/15/download.aspx?UniqueId=a-bunch-of-url-params
- this is also correct and I can download the content from a REST client, but in the browser (currently using Safari) the redirect raises a Browser cannot load [...url...] due to access control checks
error.
I have Access-Control-Allow-Origin: *
in my application headers, which is presumably why I can use Graph in the first place, but the Sharepoint response does not include Access-Control-Allow-Origin
. What more do I need to do?
You write that endpoint https://foozlecorporation-my.sharepoint.com/drive/path/_layouts/15/download.aspx?UniqueId=a-bunch-of-url-params
doesn't responds with any Access-Control-Allow-Origin
header.
When you send, from origin A, a CORS request to some endpoint on origin B (https://graph.microsoft.com
) and the response allows origin A but results in a cross-origin redirect to some endpoint on origin C (https://foozlecorporation-my.sharepoint.com
), the browser carries out a new CORS access-control check for origin A on origin C. If origin C isn't configured for CORS or doesn't allow origin A, your overall CORS request will fail.
One solution consists in making the call to https://graph.microsoft.com
from your backend rather than from your frontend; that way, because CORS doesn't apply to non-browser user agents, you'd sidestep the problem.