es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo descargar un archivo de OneDrive hacia una aplicación Angular utilizando Typescript?

Tengo una aplicación de Angular que utiliza OneDrive/Sharepoint para almacenar los archivos que crea. La autenticación funciona correctamente y puedo guardar mis archivos con éxito. Sin embargo, tengo un problema al descargar el archivo que he creado y almacenado utilizando el HttpClient de Angular.

Mi código se ve así:

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 {
   // un montón de cosas que generan los encabezados OAuth, definitivamente funcionan
}

}

Obviamente, haré algo más con la respuesta cuando pueda recibirla.

El problema es que cuando se desencadena la solicitud GET, se realiza correctamente una solicitud a graph, que luego devuelve una redirección 302 a `https://foozlecorporation-my.sharepoint.com/drive/path/_layouts/15/download.aspx?UniqueId=a-bunch-of-url-params` – Esto también es correcto y puedo descargar el contenido desde un cliente REST, pero en el navegador (actualmente utilizando Safari), la redirección genera un error de “El navegador no puede cargar […url…] debido a comprobaciones de control de acceso”.

Tengo Access-Control-Allow-Origin: * en los encabezados de mi aplicación, lo que presumiblemente me permite utilizar Graph en primer lugar, pero la respuesta de Sharepoint no incluye Access-Control-Allow-Origin. ¿Qué más debo hacer?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar relacionado con CORS (Compartir recursos de origen cruzado). Aunque la aplicación Angular tiene el encabezado Access-Control-Allow-Origin, es el servidor de SharePoint el que necesita incluir este encabezado en su respuesta.

    Para resolver este problema, puedes agregar soporte para CORS al servidor de SharePoint o utilizar un proxy para evitar las verificaciones de CORS.

    Para agregar soporte para CORS a SharePoint, debes modificar el archivo web.config del servidor para incluir los encabezados requeridos. Aquí tienes un ejemplo de lo que se debe agregar:

    <system.webserver>
      <httpprotocol>
        <customheaders>
          <add name="Access-Control-Allow-Origin" value="*"></add>
          <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization"></add>
          <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS"></add>
        </customheaders>
      </httpprotocol>
    </system.webserver>
    

    Si no puedes modificar la configuración del servidor, puedes usar un proxy para evitar las verificaciones de CORS. Una opción popular es utilizar un paquete como http-proxy-middleware en tu aplicación Angular.

    Aquí tienes un ejemplo de cómo configurar el servidor proxy para enviar solicitudes a SharePoint y agregar los encabezados requeridos para CORS:

    const proxy = require('http-proxy-middleware');
    
    module.exports = function(app) {
      app.use('/api',
        proxy({ 
          target: 'https://foozlecorporation-my.sharepoint.com',
          changeOrigin: true,
          pathRewrite: {
            '^/api': ''
          },
          onProxyRes: (proxyRes, req, res) => {
            proxyRes.headers['Access-Control-Allow-Origin'] = '*';
            proxyRes.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization';
            proxyRes.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS';
          }
        })
      );
    };
    

    Ten en cuenta que este es solo un ejemplo y deberás modificar la URL de destino y los valores de pathRewrite para que coincidan con tu API de SharePoint.

    Una vez que hayas configurado el proxy, puedes modificar tu código Angular para realizar solicitudes al proxy en lugar de hacerlo directamente a SharePoint. Por ejemplo:

    this.http.get('/api/drive/path/fileId/content', { headers: this.getOAuthHeader() })
    

    Esto debería permitirte evitar las verificaciones de CORS y descargar el archivo de SharePoint.

Comments are closed.