Cargar un archivo con la API de REST y jQuery

En los ejemplos de código de este artículo se usa la interfaz de REST y las solicitudes AJAX de jQuery para agregar un archivo local a la biblioteca Documentos y luego cambiar las propiedades del elemento de lista que representa al archivo cargado.

Este proceso comprende los siguientes pasos de alto nivel:

  1. Convierta el archivo local en un búfer de matriz mediante el uso de la API de FileReader, que requiere compatibilidad con HTML5. La función jQuery(document).ready comprueba la compatibilidad de la API de FileReader en el explorador.

  2. Agregue el archivo a la carpeta Documentos compartidos mediante el método Add en la recopilación de archivos de la carpeta. El búfer de matriz se pasa en el cuerpo de la solicitud POST.

    En estos ejemplos se usa el extremo getfolderbyserverrelativeurl para alcanzar la recopilación de archivos, pero también se puede usar un extremo de lista (por ejemplo: https://{site_url}/_api/web/lists/getbytitle('{list_title}')/rootfolder/files/add).

  3. Obtenga el elemento de lista que corresponda al archivo cargado con la propiedad ListItemAllFields del archivo cargado.

  4. Cambie el nombre para mostrar y el título del elemento de lista mediante una solicitud MERGE.

Ejecución de los ejemplos de código

En los dos ejemplos de código de este artículo se usa la API de REST y las solicitudes AJAX de jQuery para cargar un archivo en la carpeta Documentos compartidos y luego cambiar las propiedades del elemento de lista.

En el primer ejemplo, se usa SP.AppContextSite para realizar llamadas entre los dominios de SharePoint, tal como lo haría un complemento hospedado en SharePoint cuando carga archivos en la web de host.

En el segundo ejemplo, se realizan llamadas al mismo dominio, tal como lo haría un complemento hospedado en SharePoint cuando carga archivos en la web del complemento o como lo haría una solución que se ejecuta en el servidor al cargar archivos.

Nota:

Los complementos hospedados por el proveedor escritos en JavaScript deben usar el SP. Biblioteca entre dominios requestExecutor para enviar solicitudes a un dominio de SharePoint. Para conocer un ejemplo, consulte el tema sobre cómo cargar un archivo mediante la biblioteca entre dominios.

Para usar los ejemplos de este artículo, necesitará lo siguiente:

  • SharePoint Server o SharePoint Online.

  • Permisos Write para la biblioteca Documentos para el usuario que ejecuta el código. Si va a desarrollar un complemento de SharePoint, puede especificar permisos de complemento de escritura en el ámbito De lista .

  • Explorador compatible con la API de FileReader (HTML5).

  • Una referencia a la biblioteca de jQuery en el marcado de su página. Por ejemplo:

    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
    
  • Los siguientes controles en el marcado de su página.

    <input id="getFile" type="file"/><br />
    <input id="displayName" type="text" value="Enter a unique name" /><br />
    <input id="addFileButton" type="button" value="Upload" onclick="uploadFile()"/>
    

Ejemplo de código 1: Cargar un archivo en varios dominios de SharePoint con la API de REST y jQuery

En el siguiente ejemplo de código se usa la API de REST y las solicitudes AJAX de jQuery de SharePoint para cargar un archivo a la biblioteca Documentos y para cambiar las propiedades del elemento de lista que representa al archivo. El contexto para este ejemplo es un complemento hospedado por SharePoint que carga un archivo en una carpeta en la web de host.

Nota:

Para poder usar este ejemplo, debe cumplir los requisitos que aparecen en la sección Ejecutar los ejemplos de código.

'use strict';

var appWebUrl, hostWebUrl;

jQuery(document).ready(function () {
  // Check for FileReader API (HTML5) support.
  if (!window.FileReader) {
    alert('This browser does not support the FileReader API.');
  }

  // Get the add-in web and host web URLs.
  appWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
  hostWebUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
});

// Upload the file.
// You can upload files up to 2 GB with the REST API.
function uploadFile() {
  // Define the folder path for this example.
  var serverRelativeUrlToFolder = 'shared documents';

  // Get test values from the file input and text input page controls.
  // The display name must be unique every time you run the example.
  var fileInput = jQuery('#getFile');
  var newName = jQuery('#displayName').val();

  // Initiate method calls using jQuery promises.
  // Get the local file as an array buffer.
  var getFile = getFileBuffer();

  getFile.done(function (arrayBuffer) {
    // Add the file to the SharePoint folder.
    var addFile = addFileToFolder(arrayBuffer);
    addFile.done(function (file, status, xhr) {
      // Get the list item that corresponds to the uploaded file.
      var getItem = getListItem(file.d.ListItemAllFields.__deferred.uri);
      getItem.done(function (listItem, status, xhr) {
        // Change the display name and title of the list item.
        var changeItem = updateListItem(listItem.d.__metadata);
        changeItem.done(function (data, status, xhr) {
          alert('file uploaded and updated');
        });
        changeItem.fail(onError);
      });
      getItem.fail(onError);
    });
    addFile.fail(onError);
  });

  getFile.fail(onError);

  // Get the local file as an array buffer.
  function getFileBuffer() {
    var deferred = jQuery.Deferred();
    var reader = new FileReader();
    reader.onloadend = function (e) {
      deferred.resolve(e.target.result);
    }
    reader.onerror = function (e) {
      deferred.reject(e.target.error);
    }
    reader.readAsArrayBuffer(fileInput[0].files[0]);
    return deferred.promise();
  }

  // Add the file to the file collection in the Shared Documents folder.
  function addFileToFolder(arrayBuffer) {
    // Get the file name from the file input control on the page.
    var parts = fileInput[0].value.split('\\');
    var fileName = parts[parts.length - 1];

    // Construct the endpoint.
    var fileCollectionEndpoint = String.format(
        "{0}/_api/sp.appcontextsite(@target)/web/getfolderbyserverrelativeurl('{1}')/files" +
        "/add(overwrite=true, url='{2}')?@target='{3}'",
        appWebUrl, serverRelativeUrlToFolder, fileName, hostWebUrl);

    // Send the request and return the response.
    // This call returns the SharePoint file.
    return jQuery.ajax({
      url: fileCollectionEndpoint,
      type: "POST",
      data: arrayBuffer,
      processData: false,
      headers: {
        "accept": "application/json;odata=verbose",
        "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
        "content-length": arrayBuffer.byteLength
      }
    });
  }

  // Get the list item that corresponds to the file by calling the file's ListItemAllFields property.
  function getListItem(fileListItemUri) {
    // Construct the endpoint.
    // The list item URI uses the host web, but the cross-domain call is sent to the
    // add-in web and specifies the host web as the context site.
    fileListItemUri = fileListItemUri.replace(hostWebUrl, '{0}');
    fileListItemUri = fileListItemUri.replace('_api/Web', '_api/sp.appcontextsite(@target)/web');

    var listItemAllFieldsEndpoint = String.format(fileListItemUri + "?@target='{1}'", appWebUrl, hostWebUrl);

    // Send the request and return the response.
    return jQuery.ajax({
      url: listItemAllFieldsEndpoint,
      type: "GET",
      headers: { "accept": "application/json;odata=verbose" }
    });
  }

  // Change the display name and title of the list item.
  function updateListItem(itemMetadata) {
    // Construct the endpoint.
    // Specify the host web as the context site.
    var listItemUri = itemMetadata.uri.replace('_api/Web', '_api/sp.appcontextsite(@target)/web');
    var listItemEndpoint = String.format(listItemUri + "?@target='{0}'", hostWebUrl);

    // Define the list item changes. Use the FileLeafRef property to change the display name.
    // For simplicity, also use the name as the title.
    // The example gets the list item type from the item's metadata, but you can also get it from the
    // ListItemEntityTypeFullName property of the list.
    var body = String.format("{{'__metadata':{{'type':'{0}'}},'FileLeafRef':'{1}','Title':'{2}'}}",
        itemMetadata.type, newName, newName);

    // Send the request and return the promise.
    // This call does not return response content from the server.
    return jQuery.ajax({
      url: listItemEndpoint,
      type: "POST",
      data: body,
      headers: {
        "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
        "content-type": "application/json;odata=verbose",
        "content-length": body.length,
        "IF-MATCH": itemMetadata.etag,
        "X-HTTP-Method": "MERGE"
      }
    });
  }
}

// Display error messages.
function onError(error) {
  alert(error.responseText);
}

// Get parameters from the query string.
// For production purposes you may want to use a library to handle the query string.
function getQueryStringParameter(paramToRetrieve) {
  var params = document.URL.split("?")[1].split("&amp;");
  for (var i = 0; i < params.length; i = i + 1) {
    var singleParam = params[i].split("=");
    if (singleParam[0] == paramToRetrieve) return singleParam[1];
  }
}

Ejemplo de código 2: Cargar un archivo en el mismo dominio con la API de REST y jQuery

En el siguiente ejemplo de código se usa la API de REST y las solicitudes AJAX de jQuery de SharePoint para cargar un archivo en la biblioteca Documentos y para cambiar las propiedades del elemento de lista que representa el archivo. El contexto para este ejemplo es una solución que se está ejecutando en el servidor. El código sería similar en un complemento hospedado por SharePoint que carga archivos en la web del complemento.

Nota:

Para poder usar este ejemplo, debe cumplir los requisitos que aparecen en la sección Ejecutar los ejemplos de código.

'use strict';

jQuery(document).ready(function () {
  // Check for FileReader API (HTML5) support.
  if (!window.FileReader) {
    alert('This browser does not support the FileReader API.');
  }
});

// Upload the file.
// You can upload files up to 2 GB with the REST API.
function uploadFile() {
  // Define the folder path for this example.
  var serverRelativeUrlToFolder = '/shared documents';

  // Get test values from the file input and text input page controls.
  var fileInput = jQuery('#getFile');
  var newName = jQuery('#displayName').val();

  // Get the server URL.
  var serverUrl = _spPageContextInfo.webAbsoluteUrl;

  // Initiate method calls using jQuery promises.
  // Get the local file as an array buffer.
  var getFile = getFileBuffer();
  getFile.done(function (arrayBuffer) {
    // Add the file to the SharePoint folder.
    var addFile = addFileToFolder(arrayBuffer);
    addFile.done(function (file, status, xhr) {
      // Get the list item that corresponds to the uploaded file.
      var getItem = getListItem(file.d.ListItemAllFields.__deferred.uri);
      getItem.done(function (listItem, status, xhr) {
        // Change the display name and title of the list item.
        var changeItem = updateListItem(listItem.d.__metadata);
        changeItem.done(function (data, status, xhr) {
          alert('file uploaded and updated');
        });
        changeItem.fail(onError);
      });
      getItem.fail(onError);
    });
    addFile.fail(onError);
  });
  getFile.fail(onError);

  // Get the local file as an array buffer.
  function getFileBuffer() {
    var deferred = jQuery.Deferred();
    var reader = new FileReader();
    reader.onloadend = function (e) {
      deferred.resolve(e.target.result);
    }
    reader.onerror = function (e) {
      deferred.reject(e.target.error);
    }
    reader.readAsArrayBuffer(fileInput[0].files[0]);
    return deferred.promise();
  }

  // Add the file to the file collection in the Shared Documents folder.
  function addFileToFolder(arrayBuffer) {
    // Get the file name from the file input control on the page.
    var parts = fileInput[0].value.split('\\');
    var fileName = parts[parts.length - 1];

    // Construct the endpoint.
    var fileCollectionEndpoint = String.format(
            "{0}/_api/web/getfolderbyserverrelativeurl('{1}')/files" +
            "/add(overwrite=true, url='{2}')",
            serverUrl, serverRelativeUrlToFolder, fileName);

    // Send the request and return the response.
    // This call returns the SharePoint file.
    return jQuery.ajax({
        url: fileCollectionEndpoint,
        type: "POST",
        data: arrayBuffer,
        processData: false,
        headers: {
          "accept": "application/json;odata=verbose",
          "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
          "content-length": arrayBuffer.byteLength
        }
    });
  }

  // Get the list item that corresponds to the file by calling the file's ListItemAllFields property.
  function getListItem(fileListItemUri) {
    // Send the request and return the response.
    return jQuery.ajax({
      url: fileListItemUri,
      type: "GET",
      headers: { "accept": "application/json;odata=verbose" }
    });
  }

  // Change the display name and title of the list item.
  function updateListItem(itemMetadata) {
    // Define the list item changes. Use the FileLeafRef property to change the display name.
    // For simplicity, also use the name as the title.
    // The example gets the list item type from the item's metadata, but you can also get it from the
    // ListItemEntityTypeFullName property of the list.
    var body = String.format("{{'__metadata':{{'type':'{0}'}},'FileLeafRef':'{1}','Title':'{2}'}}",
        itemMetadata.type, newName, newName);

    // Send the request and return the promise.
    // This call does not return response content from the server.
    return jQuery.ajax({
        url: itemMetadata.uri,
        type: "POST",
        data: body,
        headers: {
          "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
          "content-type": "application/json;odata=verbose",
          "content-length": body.length,
          "IF-MATCH": itemMetadata.etag,
          "X-HTTP-Method": "MERGE"
        }
    });
  }
}

// Display error messages.
function onError(error) {
  alert(error.responseText);
}

Consulte también