使用 REST API 和 jQuery 上传文件

本文中的代码示例使用 REST 接口和 jQuery AJAX 请求,将本地文件添加到文档库,然后更改表示已上传文件的列表项的属性。

此过程使用以下高级步骤:

  1. 使用 FileReader API 将本地文件转换为数组缓冲区(需要 HTML5 支持)。 jQuery(document).ready 功能将在浏览器中检查 FileReader API 支持。

  2. 通过对文件夹的文件集合使用 Add 方法,将文件添加到共享文档文件夹。 在 POST 请求的正文中传递数组缓冲区。

    这些示例使用 getfolderbyserverrelativeurl 终结点到达文件集,但您也可以使用列表终结点(例如:https://{site_url}/_api/web/lists/getbytitle('{list_title}')/rootfolder/files/add)。

  3. 使用已上载文件的 ListItemAllFields 属性获取与已上载文件对应的列表项。

  4. 使用 MERGE 请求更改列表项的显示名称和标题。

运行代码示例

本文中的两个代码示例都使用 REST API 和 jQuery AJAX 请求将文件上传到共享文档文件夹,然后更改列表项属性。

第一个示例使用 SP.AppContextSite 跨 SharePoint 域执行调用,就像 SharePoint 托管加载项将文件上传到主机 Web 一样。

第二个示例在同一个域内执行调用,就像 SharePoint 托管加载项将文件上传到加载项 Web 或在服务器上运行的解决方案上传文件一样。

注意

使用 JavaScript 编写的提供商托管加载项必须使用 SP.RequestExecutor 跨域库,才能向 SharePoint 域发送请求。 有关示例,请参阅使用跨域库上传文件

若要使用本文中的示例,需要具备:

  • SharePoint Server 或 SharePoint Online。

  • 文档库的写入权限,以便用户运行代码。 如果要开发 SharePoint 加载项,可以在“列表”范围内指定“写入”外接程序权限。

  • FileReader API (HTML5) 的浏览器支持。

  • 页面标记中对 jQuery 库的引用。 例如:

    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
    
  • 页标记中的以下控件。

    <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()"/>
    

代码示例 1:使用 REST API 和 jQuery 跨 SharePoint 域上传文件

下面的代码示例使用 SharePoint REST API 和 jQuery AJAX 请求将文件上载到"文档"库,并更改表示文件的列表项的属性。 本示例的上下文是将文件上载到主机 Web 上的文件夹的 SharePoint 承载的加载项。

注意

若要使用此示例,需要满足运行代码示例一节所列的要求。

'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];
  }
}

代码示例 2:使用 REST API 和 jQuery 在同一个域内上传文件

下面的代码示例使用 SharePoint REST API 和 jQuery AJAX 请求将文件上载到"文档"库,并更改表示文件的列表项的属性。 本示例的上下文是在服务器上运行的解决方案。 代码类似于将文件上载到加载项 Web 的 SharePoint 承载的加载项中的代码。

注意

若要使用此示例,需要满足运行代码示例一节所列的要求。

'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);
}

另请参阅